#include <math.h>
#include "commerrno.h"
#include "CBattleRules.h"
#include "CBattleRandom.h"
#include "CBattleVideo.h"
#include "CBattleInf.h"
#include "../mainctrl.h"
#include "../status/CStatusMgr.h"

int CBattleRules::CheckEnd(bool& bIsEnd, int& iResult)
{
    bIsEnd = false;
    iResult = BATTLE_RESULT_WIN;

    int iCountLeft = BATTLE_INF->_pstRoles->GetLivingRoleCount(true);
    if (iCountLeft <= 0)
    {
        bIsEnd = true;
    }
    
    int iCountRight = BATTLE_INF->_pstRoles->GetLivingRoleCount(false);
    if (iCountRight <= 0)
    {
        bIsEnd = true;
    }

    int iHPNowLeft = 0;
    int iHPMaxLeft = 0;
    int iHPNowRight = 0;
    int iHPMaxRight = 0;

    //回合过长也要计算胜负
    if (!bIsEnd)
    {
        if (BATTLE_INF->_pstRoundCtrl->GetRoundNum() >= MAX_BATTLE_CIRCLE_COUNT)
        {
            CT_BATTLE(("因回合数达到上限而强制结束战斗！"));
            bIsEnd = true;
        }
    }

    if (bIsEnd)
    {
        BATTLE_INF->_pstRoles->CalcBattleTotalHP(true, iHPNowLeft, iHPMaxLeft);
        BATTLE_INF->_pstRoles->CalcBattleTotalHP(false, iHPNowRight,
            iHPMaxRight);
        if (iHPNowRight > iHPNowLeft)
        {
            iResult = BATTLE_RESULT_LOST;
        }
        else if (iHPNowRight <= 0 &&  iHPNowLeft <= 0 &&
                    BATTLE_INF->_pstRoles->GetRightDeadBomb())
        {
            iResult = BATTLE_RESULT_LOST;
        }
    }    

    return 0;
}

int CBattleRules::DealAtBattleBegin()
{
    //处理一进战斗就怒气满情况需要输出怒气满状态
    for(int i = 0; i < BATTLE_INF->_pstRoles->GetRoleCount(); ++i)
    {
        CBattleRole& stBattleRole = BATTLE_INF->_pstRoles->GetRole(i);
        if (stBattleRole.GetAnger() >= stBattleRole.GetAngerMax()
            && !stBattleRole.IsAngerFull())
        {
            stBattleRole.SetAngerFull();
            BATTLE_INF->_pstVideo->RoleAngerStat(stBattleRole.GetRoleID(),
                BATTLE_VIDEO_ANGER_ADD);
        }
    }

    BATTLE_INF->_pstRoles->SetRightDeadBomb(false);

    return 0;
}

int CBattleRules::DealAtTurnBegin()
{
    //每回合开始设置每个个体伤害前的血量
    for(int i = 0; i < BATTLE_INF->_pstRoles->GetRoleCount(); ++i)
    {
        CBattleRole& stBattleRole = BATTLE_INF->_pstRoles->GetRole(i);
        stBattleRole.SetHPBeforeAtk(stBattleRole.GetHP());
    }

    return 0;
}

int CBattleRules::GetTurn(int iRoleID)
{
    if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
    {
        return 0;
    }
    CT_BATTLE(("角色(%d)动作开始", iRoleID));
    BATTLE_INF->_pstVideo->TurnBegin(iRoleID);

    CBattleRole& stBattleRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
    if (stBattleRole.HasDead())
    {
        return 0;
    }

    int iRet = 0;
    _bTurnOver = false;

    stBattleRole._iUseAnger = 0;//用于记录本次高阶技能消耗的怒气 必须初始化
    _stCastSkill.Clear();
    _stSpecialTarget.Clear();
    _stBattleReviseAtk.Clear();
    BattleReviseInit(stBattleRole);

    DealAtTurnBegin();

    SetNowAttack(stBattleRole.GetRoleID()); //设置当前攻击者ID

    SetRuleStat(BATTLE_RULE_STAT_PRE_SKILL);//预执行技能阶段

    iRet = CBattleRules::RolePreSkill(stBattleRole);
    CT_RETURN(iRet);

    if (stBattleRole.HasDead())
    {
        return 0;
    }

    SetRuleStat(BATTLE_RULE_STAT_PREPARE);//战斗准备阶段

    //效果结算
    iRet = CheckBuffBeforeTurn(stBattleRole);
    CT_RETURN(iRet);

    if (_bTurnOver)
    {
        return 0;
    }

    //Buff中修改了当前攻击者 这里修改回当前角色
    SetNowAttack(stBattleRole.GetRoleID()); //设置当前攻击者ID

    //判断是否可以行动
    iRet = CheckCanDoTurn(stBattleRole);
    CT_RETURN(iRet);

    if (_bTurnOver)
    {
        return 0;
    }

    SetRuleStat(BATTLE_RULE_STAT_SKILL_TARGET);//技能和目标阶段

    //状态处理 STATUS_TRIGGER_TURN_START //回合行动时触发 移动前 发出技能前 +
    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stBattleRole,
        CStatusMgr::STATUS_TRIGGER_TURN_START, 0);

    //累计队伍出手次数
    AddBattleTurnTimes(stBattleRole.IsLeft());

    //选择技能和目标
    iRet = ChooseSkillAndGetTarget(stBattleRole);
    CT_RETURN(iRet);

    if (_bTurnOver)
    {
        return 0;
    }

    //施法者及受击者叠加Buff加成属性计算
    iRet = CastSkillEffectAttr(stBattleRole);
    CT_RETURN(iRet);

    //施法者及受击者预处理回合数据处理
    iRet = CastSkillPreEffect(stBattleRole, true);
    CT_RETURN(iRet);
    iRet = CastSkillPreEffect(stBattleRole, false);
    CT_RETURN(iRet);

    DealAtTurnBegin();

    //发动技能
    CT_BATTLE(("开始发动技能"));
    iRet = CastSkill(stBattleRole, _stCastSkill,
        _stSkillCastFirstEffect._astTargets[0].GetID());
    CT_RETURN(iRet);

    //数据变化
    CT_BATTLE(("开始结算技能效果"));
    iRet = CastSkillEffect(stBattleRole, _stCastSkill);
    CT_RETURN(iRet);

    return 0;
}

void CBattleRules::AddBattleTurnTimes(bool bIsLeft)
{
    if (bIsLeft)
    {
        _stBattleInfoCount.SetLeftTurnTimes(
            _stBattleInfoCount.GetLeftTurnTimes() + 1);
    }
    else
    {
        _stBattleInfoCount.SetRightTurnTimes(
            _stBattleInfoCount.GetRightTurnTimes() + 1);
    }
}

int CBattleRules::CheckBuffBeforeTurn(CBattleRole& stBattleRole)
{
    int iRet = stBattleRole.CalcBuffBeforeTurn(_bTurnOver);
    CT_RETURN(iRet);

    return 0;
}

int CBattleRules::CheckCanDoTurn(CBattleRole& stBattleRole)
{
    if (stBattleRole.HasDead())
    {
        _bTurnOver = true;
        return 0;
    }

    if (stBattleRole.IsHaveToTurnWait())
    {
        CT_BATTLE(("角色(%d)勇气状态回合等待，本回合立即结束",
            stBattleRole.GetRoleID()));
        stBattleRole.SetRecvCourageAndAct();
        _bTurnOver = true;
        return 0;
    }


    //因为Buff扣光勇气 这里执行撤退
    if (stBattleRole.IsFallBackRightNow() && !stBattleRole.IsSwim() && !stBattleRole.IsStick())
    {
        BATTLE_INF->_pstVideo->RoleFallBack(stBattleRole.GetRoleID());

        int iDstGrid = CT_MAX(0, stBattleRole.GetRelatGridIndex(stBattleRole.IsLeft()) - BATTLE_FALLBACK_DISTANCE);
        if (iDstGrid != stBattleRole.GetRelatGridIndex(stBattleRole.IsLeft()))
        {
            int iRet = RoleMoveTo(stBattleRole, iDstGrid, true);
            CT_RETURN(iRet);
            CT_BATTLE(("角色(%d)撤退到格子(%d)",stBattleRole.GetRoleID(),stBattleRole.GetGridIndex()));
        }
        stBattleRole.SetRoleTurnWait();
        _bTurnOver = true;
        return 0;
    }

    if (stBattleRole.IsRecvCourageAndAct())
    {
        stBattleRole.RecvCourageAndAct();
    }

    if (stBattleRole.IsNoCourage())
    {
        CT_BATTLE(("勇气值为0"));
        BATTLE_INF->_pstVideo->NoCourageTurnEnd(stBattleRole.GetRoleID());
        _bTurnOver = true;
        return 0;
    }

    CT_BATTLE(("可以执行回合"));

    return 0;
}

int CBattleRules::ChooseSkillAndGetTarget(CBattleRole& stBattleRole)
{
    int iRet = 0;

    //幻化技能
    CT_BATTLE(("当前怒气(%d), 幻化技能需要怒气(%d)",stBattleRole.GetAnger(),
        stBattleRole._stRoleBase._stMagicSkill.GetUseAnger()));

    if (stBattleRole.CanCastMagicSkill())
    {
        CT_BATTLE(("角色(%d)可以释放幻化技能(%d)",stBattleRole.GetRoleID(),
            stBattleRole._stRoleBase._stMagicSkill.GetID()));

        stBattleRole.GetMagicSkill(_stCastSkill);
        
        iRet = FindTargets(stBattleRole, _stCastSkill);
        CT_RETURN(iRet);

        if (IsFindMainTarget())
        {
            return 0;//已经找到目标直接退出
        }
    }

    CT_BATTLE(("角色(%d)不能释放幻化技能(%d)", stBattleRole.GetRoleID(),
        stBattleRole._stRoleBase._stMagicSkill.GetID()));
#if 0
    CT_BATTLE(("当前普攻次数(%d), 学院技能需要次数(%d)",
        stBattleRole.GetHasDoNormalAtkCount(), MAX_NORMAL_ATK_BEFORE_ACAD));
    if (stBattleRole.CanCastAcadSkill())
    {
        CT_BATTLE(("角色(%d)可以释放学院技能(%d)", stBattleRole.GetRoleID(),
                    stBattleRole._stRoleBase._stAcadSkill.GetID()));

        stBattleRole.GetAcadSkill(_stCastSkill);

       iRet = FindTargets(stBattleRole, _stCastSkill);
       CT_RETURN(iRet);

       if (IsFindMainTarget())
       {
           stBattleRole.CleanHasDoNormalAtkCount();
           return 0;
       }
    }

    CT_BATTLE(("角色(%d)不能释放学院技能(%d)", stBattleRole.GetRoleID(),
                stBattleRole._stRoleBase._stAcadSkill.GetID()));
#endif

    if (!stBattleRole.CanCastNormalSkill())
    {
        CT_BATTLE(("角色(%d)没有配置普通技能(%d)",stBattleRole.GetRoleID(),
            stBattleRole._stRoleBase._stNormalSkill.GetID()));
        _bTurnOver = true;
        return 0;
    }

    CT_BATTLE(("角色(%d)释放普通技能(%d)",stBattleRole.GetRoleID(),
        stBattleRole._stRoleBase._stNormalSkill.GetID()));

    //普通攻击
    stBattleRole.GetNormalSkill(_stCastSkill);
    
    iRet = FindTargets(stBattleRole, _stCastSkill);
    CT_RETURN(iRet);

    if (IsFindMainTarget())
    {
        stBattleRole.AddHasDoNormalAtkCount();
    }
    else
    {
        CT_BATTLE(("角色(%d)没有目标而不能释放技能",stBattleRole.GetRoleID()));
        BATTLE_INF->_pstVideo->CanNotUseSkill(stBattleRole.GetRoleID());
        _bTurnOver = true;
    }

    return 0;
}

int CBattleRules::FindTargets(CBattleRole& stBattleRole, CSkill& stSkill)
{
    int iRet = 0;

    SetSkillType(stSkill.GetType());

    //每次确定重新找目标都需要清掉原来的目标
    _stSkillCastFirstEffect.Clear();
    _stSkillCastSecondEffect.Clear();

    if (stSkill.MainSkillHasMainTargetStru()) //有主目标的攻击
    {
        iRet = stSkill.GetMainSkillAffect(
            _stSkillCastFirstEffect._stSkillAffect);
        CT_RETURN(iRet);

        CT_BATTLE(("在原地检查是否有攻击主目标"));

        iRet = MainTargetChoose(stBattleRole, _stSkillCastFirstEffect, false);
        CT_RETURN(iRet);

        if (!IsFindMainTarget() && !stBattleRole.IsStick())
        {
            CT_BATTLE(("移动后检查是否有攻击主目标"));
            iRet = MainTargetChoose(stBattleRole, _stSkillCastFirstEffect,
                true);
            CT_RETURN(iRet);
        }

        if (!IsFindMainTarget())
        {
            CT_BATTLE(("没有攻击主目标 目标查找结束"));
            return 0;
        }

        if (stSkill.MinorSkillHasMainTargetStru()) //波及目标也是主目标结构
        {
            iRet = stSkill.GetMinorSkillAffect(
                _stSkillCastSecondEffect._stSkillAffect);
            CT_RETURN(iRet);

            iRet = MainTargetChoose(stBattleRole, _stSkillCastSecondEffect,
                false);//策划把握攻击距离这里作为辅助目标不能移动
            CT_RETURN(iRet);
        }
        else if (stSkill.SkillHasMinorCentreInvo()) //计算波及中心范围内目标
        {
            CT_BATTLE(("检查波及中心范围内目标"));
            iRet = GetMinorCentreInvoTarget(stBattleRole, stSkill);
            CT_RETURN(iRet);
        }
        else if (stSkill.SkillHasMinorDistanInvo()) //计算波及一段距离上目标
        {
            CT_BATTLE(("检查波及一段距离上目标"));
            iRet = GetMinorDistanInvoTarget(stBattleRole, stSkill);
            CT_RETURN(iRet);
        } 
        else if (stSkill.SkillHasMinorBackInvo()) //计算波及身后距离目标
        {
            CT_BATTLE(("检查波及身后距离目标"));
            iRet = GetMinorBackInvoTarget(stBattleRole, stSkill);
            CT_RETURN(iRet);
        } 
        else if (stSkill.SkillHasMinorOneselfInvo()) //计算波及目标施法者自己
        {
            CT_BATTLE(("检查波及目标施法者自己"));
            iRet = GetMinorOneselfInvoTarget(stBattleRole, stSkill);
            CT_RETURN(iRet);
        }
        else if (stSkill.SkillHasMinorMainInvo()) //计算波及主目标
        {
            CT_BATTLE(("检查波及主目标"));
            iRet = GetMinorMainInvoTarget(stBattleRole, stSkill);
            CT_RETURN(iRet);
        }
        else if (stSkill.MinorSkillHasGroupTargetStru()) //波及群体
        {
            CT_BATTLE(("检查波及群体目标"));
            iRet = GetGroupTarget(stBattleRole, stSkill, false);
            CT_RETURN(iRet);
        }

        //策划要求波及目标不再包含主目标
        if (IsFindMainTarget() && IsFindMinorTarget()
            && !stSkill.SkillHasMinorMainInvo())
        {
            for (int i = 0; i < _stSkillCastSecondEffect._astTargets.Size(); )
            {
                if (_stSkillCastSecondEffect._astTargets[i].GetID()
                        == _stSkillCastFirstEffect._astTargets[0].GetID())
                {
                    _stSkillCastSecondEffect._astTargets.DelOneItem(i);
                }
                else
                {
                    ++i;
                }
            }
        }
    }
    else if (stSkill.MainSkillHasGroupTargetStru()) //主群攻
    {
        CT_BATTLE(("技能是群攻技能"));
        iRet = GetGroupTarget(stBattleRole, stSkill, true);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleRules::MainTargetSelect(CBattleRole& stBattleRole,
        CBattleSkillCastEffect& stCastEffect, MAP_GRID_MULTI& stMapGridMulti)
{
    if (CSkillAffect::SKILL_TARGET_ONESELF !=
            stCastEffect._stSkillAffect.GetTargetType())
    {
        //普通主目标不能包含自身 明确主目标为角色自己除外 因秘宝预执行技能放开
        for (int i = 0; i < stMapGridMulti.Size(); )//不能自增 放在逻辑里面
        {
            if (stBattleRole.GetRoleID() == stMapGridMulti[i].GetRoleID())
            {
                stMapGridMulti.DelOneItem(i);
            }
            else
            {
                ++i;
            }
        }
    }

    if (stMapGridMulti.Size() <= 0)
    {
        return 0;
    }

    bool bLeftSide = stBattleRole.IsLeft();
    int iRoleID = 0;

#ifdef _DEBUG
    CT_BATTLE(("遴选主目标前打印:目标总数(%d)",stMapGridMulti.Size()));
    for (int i = 0; i < stMapGridMulti.Size(); ++i)
    {
        iRoleID = stMapGridMulti[i].GetRoleID();
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

        CT_BATTLE(("攻击者是否左方(%d)候选角色(%d)相对站位(%d)原始站位(%d)" \
                   "生命上限(%d)",bLeftSide,stTargetRole.GetRoleID(),
                   stTargetRole.GetRelatGridIndex(bLeftSide),
                   stTargetRole.GetOriginalPos(),stTargetRole.GetHPMax()));
    }
#endif
    //因下面相互赋值 必须临时变量
    CBattleRole stRoleTmp1;
    CBattleRole stRoleTmp2;
            
    switch(stCastEffect._stSkillAffect.GetTargetType())
    {
    case CSkillAffect::SKILL_TARGET_NEAREST:
    case CSkillAffect::SKILL_TARGET_NEAR_WHOLE:
    case CSkillAffect::SKILL_TARGET_NEAR_FRONT:
    case CSkillAffect::SKILL_TARGET_NEAR_BACK:
    case CSkillAffect::SKILL_TARGET_NEAR_SWORD:
    case CSkillAffect::SKILL_TARGET_NEAR_BOW:
    case CSkillAffect::SKILL_TARGET_NEAR_MAGE:
    case CSkillAffect::SKILL_TARGET_NEAR_AWL:
        {
            BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[0].GetRoleID(),
                stRoleTmp1);
            
            for (int i = 1; i < stMapGridMulti.Size(); ++i)
            {
                BATTLE_INF->_pstRoles->GetRole(
                    stMapGridMulti[i].GetRoleID(), stRoleTmp2);
            
                if (stCastEffect._stSkillAffect.IsToEnemy() &&
                        stRoleTmp1.GetRelatGridIndex(bLeftSide) >
                            stRoleTmp2.GetRelatGridIndex(bLeftSide))
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (!stCastEffect._stSkillAffect.IsToEnemy() &&
                         (abs(stRoleTmp1.GetRelatGridIndex(bLeftSide)
                              - stBattleRole.GetRelatGridIndex(bLeftSide))
                          > abs(stRoleTmp2.GetRelatGridIndex(bLeftSide)
                                - stBattleRole.GetRelatGridIndex(bLeftSide))))
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (stRoleTmp1.GetRelatGridIndex(bLeftSide) ==
                            stRoleTmp2.GetRelatGridIndex(bLeftSide))
                {
                    if (stRoleTmp1.GetOriginalPos() <
                            stRoleTmp2.GetOriginalPos())
                    {
                        stRoleTmp1 = stRoleTmp2;
                    }
                }
            }
            
            CBattleSkillTarget stSkillTarget(stRoleTmp1.GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_FAR_WHOLE:
        {
            BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[0].GetRoleID(),
                stRoleTmp1);
            
            for (int i = 1; i < stMapGridMulti.Size(); ++i)
            {
                BATTLE_INF->_pstRoles->GetRole(
                    stMapGridMulti[i].GetRoleID(), stRoleTmp2);
            
                if (stCastEffect._stSkillAffect.IsToEnemy() &&
                        stRoleTmp1.GetRelatGridIndex(bLeftSide) <
                            stRoleTmp2.GetRelatGridIndex(bLeftSide))
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (!stCastEffect._stSkillAffect.IsToEnemy() &&
                         (abs(stRoleTmp1.GetRelatGridIndex(bLeftSide)
                              - stBattleRole.GetRelatGridIndex(bLeftSide))
                          < abs(stRoleTmp2.GetRelatGridIndex(bLeftSide)
                                - stBattleRole.GetRelatGridIndex(bLeftSide))))
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (stRoleTmp1.GetRelatGridIndex(bLeftSide) ==
                            stRoleTmp2.GetRelatGridIndex(bLeftSide))
                {
                    if (stRoleTmp1.GetOriginalPos() >
                            stRoleTmp2.GetOriginalPos())
                    {
                        stRoleTmp1 = stRoleTmp2;
                    }
                }
            }
            
            CBattleSkillTarget stSkillTarget(stRoleTmp1.GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ALL_RANDOM:
        {
            int iRand = CBattleRandom::GetRand(stMapGridMulti.Size());
            CBattleSkillTarget stSkillTarget(stMapGridMulti[iRand].GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_HP_LOWEST:
        {
            BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[0].GetRoleID(),
                stRoleTmp1);
            
            for (int i = 1; i < stMapGridMulti.Size(); ++i)
            {
                BATTLE_INF->_pstRoles->GetRole(
                    stMapGridMulti[i].GetRoleID(), stRoleTmp2);
            
                if (stRoleTmp1.GetHPMax() > stRoleTmp2.GetHPMax())
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (stRoleTmp1.GetHPMax() == stRoleTmp2.GetHPMax())
                {
                    if (stRoleTmp1.GetOriginalPos() <
                            stRoleTmp2.GetOriginalPos())
                    {
                        stRoleTmp1 = stRoleTmp2;
                    }
                }
            }
            
            CBattleSkillTarget stSkillTarget(stRoleTmp1.GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_HP_HIGHEST:
        {
            BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[0].GetRoleID(),
                stRoleTmp1);
            
            for (int i = 1; i < stMapGridMulti.Size(); ++i)
            {
                BATTLE_INF->_pstRoles->GetRole(
                    stMapGridMulti[i].GetRoleID(), stRoleTmp2);
            
                if (stRoleTmp1.GetHPMax() < stRoleTmp2.GetHPMax())
                {
                    stRoleTmp1 = stRoleTmp2;
                }
                else if (stRoleTmp1.GetHPMax() == stRoleTmp2.GetHPMax())
                {
                    if (stRoleTmp1.GetOriginalPos() <
                            stRoleTmp2.GetOriginalPos())
                    {
                        stRoleTmp1 = stRoleTmp2;
                    }
                }
            }
            
            CBattleSkillTarget stSkillTarget(stRoleTmp1.GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ONESELF:
        {
            CBattleSkillTarget stSkillTarget(stBattleRole.GetRoleID());
            stCastEffect._astTargets.AddOneItem(stSkillTarget);
        }
        break;
    case CSkillAffect::SKILL_TARGET_PLAYER:
        {
            for (int i = 0; i < stMapGridMulti.Size(); ++i)
            {
                iRoleID = stMapGridMulti[i].GetRoleID();
                if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
                {
                    continue;
                }
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(iRoleID);
            
                if (stTargetRole.IsPlayerObject())
                {
                    CBattleSkillTarget stSkillTarget(stTargetRole.GetRoleID());
                    stCastEffect._astTargets.AddOneItem(stSkillTarget);
                }
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_PARTNER:
        {
            for (int i = 0; i < stMapGridMulti.Size(); ++i)
            {
                iRoleID = stMapGridMulti[i].GetRoleID();
                if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
                {
                    continue;
                }
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(iRoleID);
            
                if (stTargetRole.IsPartnerObject())
                {
                    CBattleSkillTarget stSkillTarget(stTargetRole.GetRoleID());
                    stCastEffect._astTargets.AddOneItem(stSkillTarget);
                }
            }
        }
        break;
    default:
        break;
    }

    if (stCastEffect._astTargets.Size() > 0)
    {
        iRoleID = stCastEffect._astTargets[0].GetID();//主目标至多选出一个目标
        if (BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            CT_BATTLE(("被选中的主目标角色(%d)",iRoleID));
            CBattleRole& stBattleTarget =
                BATTLE_INF->_pstRoles->GetRole(iRoleID);
            stCastEffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_MAIN;
            stCastEffect._chTargetFromPos = stBattleTarget.GetGridIndex();
            stCastEffect._chTargetEndPos = stBattleTarget.GetGridIndex();
            SetNowTarget(iRoleID);//设置当前受击者
        }
    }

    return 0;
}

int CBattleRules::MainTargetChoose(CBattleRole& stBattleRole,
        CBattleSkillCastEffect& stCastEffect, bool bMove)
{
    int iRet = 0;

    CSkillAffect& stMainSkillAffect = stCastEffect._stSkillAffect;

    CT_BATTLE(("主技能功能是否对敌释放(%d)", stMainSkillAffect.IsToEnemy()));

    CMapSide& stMapSide =
        BATTLE_INF->_pstMap->GetMapSide(stBattleRole.IsLeft());

    int iMyGrid = stBattleRole.GetRelatGridIndex(stBattleRole.IsLeft());

    int iAtkDist = stMainSkillAffect.GetMaxAtkDistance();
    iAtkDist = iAtkDist < 0 ? 0 : iAtkDist;

    int iAddDist = bMove ? stMapSide.GetRightFrontTo() - iMyGrid : 0;
    int iSrcPos = 0;
    int iDstPos = stMapSide.GetLeftFrontTo();

    if (stMainSkillAffect.IsToEnemy())
    {
        iDstPos = iMyGrid + iAtkDist + iAddDist;
        iDstPos = iDstPos >= MAX_BATTLE_GRIDS ? MAX_BATTLE_GRIDS - 1 : iDstPos;
        switch (stMainSkillAffect.GetTargetType())
        {
        case CSkillAffect::SKILL_TARGET_NEAREST:
        case CSkillAffect::SKILL_TARGET_NEAR_WHOLE:
        case CSkillAffect::SKILL_TARGET_NEAR_SWORD:
        case CSkillAffect::SKILL_TARGET_NEAR_BOW:
        case CSkillAffect::SKILL_TARGET_NEAR_MAGE:
        case CSkillAffect::SKILL_TARGET_NEAR_AWL:
        case CSkillAffect::SKILL_TARGET_FAR_WHOLE:
        case CSkillAffect::SKILL_TARGET_ALL_RANDOM:
        case CSkillAffect::SKILL_TARGET_HP_LOWEST:
        case CSkillAffect::SKILL_TARGET_HP_HIGHEST:
        case CSkillAffect::SKILL_TARGET_PLAYER:
        case CSkillAffect::SKILL_TARGET_PARTNER:
            {
                if (iDstPos < stMapSide.GetRightFrontTo())
                {
                    return 0;
                }
                iSrcPos = stMapSide.GetRightFrontTo();
            }
            break;
        case CSkillAffect::SKILL_TARGET_NEAR_FRONT:
            {
                if (iDstPos < stMapSide.GetRightFrontTo())
                {
                    return 0;
                }
                if (iDstPos >= stMapSide.GetRightBackTo() &&
                    stMapSide.GetRightBackTo() > stMapSide.GetRightFrontTo())
                {
                    iDstPos = stMapSide.GetRightBackTo() - 1;
                }
                iSrcPos = stMapSide.GetRightFrontTo();
            }
            break;
        case CSkillAffect::SKILL_TARGET_NEAR_BACK:
            {
                if (iDstPos < stMapSide.GetRightBackTo())
                {
                    return 0;
                }
                iSrcPos = stMapSide.GetRightBackTo();
            }
            break;
        default:
            break;
        }
    }

    MAP_GRID_MULTI stMapGridMulti;
    
    CT_BATTLE(("主技能目标类型(%d)", stMainSkillAffect.GetTargetType()));
    switch(stMainSkillAffect.GetTargetType())
    {
    case CSkillAffect::SKILL_TARGET_NEAREST:
    case CSkillAffect::SKILL_TARGET_NEAR_WHOLE:
    case CSkillAffect::SKILL_TARGET_NEAR_FRONT:
    case CSkillAffect::SKILL_TARGET_NEAR_BACK:
    case CSkillAffect::SKILL_TARGET_FAR_WHOLE:
    case CSkillAffect::SKILL_TARGET_ALL_RANDOM:
    case CSkillAffect::SKILL_TARGET_HP_LOWEST:
    case CSkillAffect::SKILL_TARGET_HP_HIGHEST:
    case CSkillAffect::SKILL_TARGET_PLAYER:
    case CSkillAffect::SKILL_TARGET_PARTNER:
        {
            iRet = stMapSide.GetDistanceRoles(iSrcPos, iDstPos, stMapGridMulti);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_NEAR_SWORD:
        {
            iRet = stMapSide.GetDistanceCareerRoles(iSrcPos, iDstPos,
                stMapGridMulti, CAREER_1);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_NEAR_BOW:
        {
            iRet = stMapSide.GetDistanceCareerRoles(iSrcPos, iDstPos,
                stMapGridMulti, CAREER_3);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_NEAR_MAGE:
        {
            iRet = stMapSide.GetDistanceCareerRoles(iSrcPos, iDstPos,
                stMapGridMulti, CAREER_2);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_NEAR_AWL:
        {
            iRet = stMapSide.GetDistanceCareerRoles(iSrcPos, iDstPos,
                stMapGridMulti, CAREER_4);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ONESELF:
        {
            stMapGridMulti.Clear();
            CGridUnit stGridUnit;
            stGridUnit.SetRoleID(stBattleRole.GetRoleID());
            stMapGridMulti.AddOneItem(stGridUnit);
        }
        break;
    default:
        break;
    }

    return MainTargetSelect(stBattleRole, stCastEffect, stMapGridMulti);
}

int CBattleRules::StatusTargetChoose(CBattleRole& stBattleRole,
        CSkillAffect& stSkillAffect, MAP_GRID_MULTI& stMapGridMulti)
{
    int iRet = 0;
    stMapGridMulti.Clear();

    if (!stSkillAffect.IsTargetStruMain() &&
        !stSkillAffect.IsTargetStruGroup())
    {
        return ERROR_NO_STATUS_SKILL_EFFECT;
    }

    CMapSide& stMapSide =
        BATTLE_INF->_pstMap->GetMapSide(stBattleRole.IsLeft());

    CT_BATTLE(("状态功能(%u)搜索目标类型(%d)开始",stSkillAffect.GetID(),
               stSkillAffect.GetTargetType()));

    switch (stSkillAffect.GetTargetType())
    {
    case CSkillAffect::SKILL_TARGET_ONESELF://角色自己
        {
            CGridUnit stGridUnit;
            stGridUnit.SetRoleID(stBattleRole.GetRoleID());
            stMapGridMulti.AddOneItem(stGridUnit);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ALL_TEAMMATE://所有队友
        {
            iRet = stMapSide.GetDistanceRoles(0, stMapSide.GetLeftFrontTo(),
                stMapGridMulti);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ALL_ENEMY://所有敌人
        {
            iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightFrontTo(),
                MAX_BATTLE_GRIDS - 1, stMapGridMulti);
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ENEMY_I_ATK://当前攻击敌人
        {
            CGridUnit stGridUnit;

            if (BATTLE_INF->_pstRoles->IsValidRoleID(GetNowTarget()))
            {
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(GetNowTarget());
                if (stBattleRole.IsLeft() != stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_ENEMY_SKILL://技能所指敌人
        {
            CGridUnit stGridUnit;

            int iRoleID = 0;
            CBattleSkillCastEffect& stFirstCastEffect = _stSkillCastFirstEffect;
            for (int i = 0; i < stFirstCastEffect._astTargets.Size(); ++i)
            {
                iRoleID = stFirstCastEffect._astTargets[i].GetID();
                if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
                {
                    continue;
                }

                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(iRoleID);
                
                if (stBattleRole.IsLeft() != stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }

            CBattleSkillCastEffect& stSecCastEffect = _stSkillCastSecondEffect;
            for (int i = 0; i < stSecCastEffect._astTargets.Size(); ++i)
            {
                iRoleID = stSecCastEffect._astTargets[i].GetID();
                if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
                {
                    continue;
                }
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(iRoleID);
                
                if (stBattleRole.IsLeft() != stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_ENEMY_TO_ME://攻击我的敌人
        {
            CGridUnit stGridUnit;

            if (BATTLE_INF->_pstRoles->IsValidRoleID(GetNowAttack()))
            {
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(GetNowAttack());
                if (stBattleRole.IsLeft() != stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_ENEMY_KILL_ME://杀死我的敌人
        {
            CGridUnit stGridUnit;

            if (BATTLE_INF->_pstRoles->IsValidRoleID(GetNowKiller()))
            {
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(GetNowKiller());
                if (stBattleRole.HasDead() &&
                    stBattleRole.IsLeft() != stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_TEAMMATE_AFF://对我使用技能的队友
        {
            CGridUnit stGridUnit;

            if (BATTLE_INF->_pstRoles->IsValidRoleID(GetNowAttack()))
            {
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(GetNowAttack());
                if (stBattleRole.IsLeft() == stTargetRole.IsLeft())
                {
                    stGridUnit.SetRoleID(stTargetRole.GetRoleID());
                    stMapGridMulti.AddOneItem(stGridUnit);
                }
            }
        }
        break;
    default:
        break;
    }

    CT_BATTLE(("状态功能(%u)搜索目标类型(%d)结束:目标总数(%d)",
               stSkillAffect.GetID(),stSkillAffect.GetTargetType(),
               stMapGridMulti.Size()));

    return 0;
}

int CBattleRules::GetMinorDistanInvoTarget(CBattleRole& stRole, CSkill& stSkill)
{
    int iRet = 0;

    stSkill.GetMinorSkillAffect(_stSkillCastSecondEffect._stSkillAffect);

    CBattleRole stTargetRole;
    int iMainTargetID = _stSkillCastFirstEffect._astTargets[0].GetID();
    iRet = BATTLE_INF->_pstRoles->GetRole(iMainTargetID, stTargetRole);
    CT_RETURN(iRet);

    bool bLeftSide = stRole.IsLeft();
    CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

    int iSrcPos = stRole.GetRelatGridIndex(bLeftSide);
    int iDstPos = stTargetRole.GetRelatGridIndex(bLeftSide);

    if (iSrcPos > iDstPos)
    {
        int iTmp = iSrcPos;
        iSrcPos = iDstPos;
        iDstPos = iTmp;
    }

    MAP_GRID_MULTI stMapGridMulti;
    iRet = stMapSide.GetDistanceSideRoles(iSrcPos, iDstPos, stMapGridMulti,
        stTargetRole.IsLeft());
    CT_RETURN(iRet);

    for (int i = 0; i < stMapGridMulti.Size(); ++i)
    {
        if (stMapGridMulti[i].GetRoleID() != iMainTargetID)
        {
            CT_BATTLE(("确定波及一段距离上目标角色(%d)", stMapGridMulti[i].GetRoleID()));
            CBattleSkillTarget stSkillTarget(stMapGridMulti[i].GetRoleID());
            _stSkillCastSecondEffect._astTargets.AddOneItem(stSkillTarget);
        }
    }

    if (_stSkillCastSecondEffect._astTargets.Size() > 0)
    {
        _stSkillCastSecondEffect._chTargetType = VIDEO_EXE_SKILL_DISTAN_GROUP;
        _stSkillCastSecondEffect._chTargetFromPos = stRole.GetGridIndex();
        _stSkillCastSecondEffect._chTargetEndPos = stTargetRole.GetGridIndex();
    }

    return 0;
}

int CBattleRules::GetMinorCentreInvoTarget(CBattleRole& stRole, CSkill& stSkill)
{
    int iRet = 0;

    stSkill.GetMinorSkillAffect(_stSkillCastSecondEffect._stSkillAffect);

    CSkillAffect& stMinorAffect = _stSkillCastSecondEffect._stSkillAffect;

    CT_BATTLE(("开始查找波及中心范围内目标(波及范围值%d)",
        stMinorAffect.GetEffectRange()));

    CBattleRole stTargetRole;
    int iMainTargetID = _stSkillCastFirstEffect._astTargets[0].GetID();
    iRet = BATTLE_INF->_pstRoles->GetRole(iMainTargetID, stTargetRole);
    CT_RETURN(iRet);

    bool bLeftSide = stRole.IsLeft();
    CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

    int iRange =
        stMinorAffect.GetEffectRange() < 0 ? 0 : stMinorAffect.GetEffectRange();
    int iSrcPos = stTargetRole.GetRelatGridIndex(bLeftSide) - iRange;
    int iDstPos = stTargetRole.GetRelatGridIndex(bLeftSide) + iRange;
    iSrcPos = iSrcPos < 0 ? 0 : iSrcPos;
    iDstPos = iDstPos >= MAX_BATTLE_GRIDS ? MAX_BATTLE_GRIDS - 1 : iDstPos;

    MAP_GRID_MULTI stMapGridMulti;
    iRet = stMapSide.GetDistanceSideRoles(iSrcPos, iDstPos, stMapGridMulti,
        stTargetRole.IsLeft());
    CT_RETURN(iRet);

    for (int i = 0; i < stMapGridMulti.Size(); ++i)
    {
        if (stMapGridMulti[i].GetRoleID() != iMainTargetID)
        {
            CT_BATTLE(("确定波及中心范围内目标角色(%d)",
                stMapGridMulti[i].GetRoleID()));
            CBattleSkillTarget stSkillTarget(stMapGridMulti[i].GetRoleID());
            _stSkillCastSecondEffect._astTargets.AddOneItem(stSkillTarget);
        }
    }

    if (_stSkillCastSecondEffect._astTargets.Size() > 0)
    {
        _stSkillCastSecondEffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_GROUP;
        _stSkillCastSecondEffect._chTargetFromPos = bLeftSide ? iSrcPos : MAX_BATTLE_GRIDS - 1 - iSrcPos;
        _stSkillCastSecondEffect._chTargetEndPos = bLeftSide ? iDstPos : MAX_BATTLE_GRIDS - 1 - iDstPos;
    }

    return 0;
}

int CBattleRules::GetMinorOneselfInvoTarget(CBattleRole& stRole,
        CSkill& stSkill)
{
    int iRet = stSkill.GetMinorSkillAffect(
        _stSkillCastSecondEffect._stSkillAffect);
    CT_RETURN(iRet);    

    CT_BATTLE(("确定波及施法者自己角色(%d)", stRole.GetRoleID()));
    CBattleSkillTarget stSkillTarget(stRole.GetRoleID());
    _stSkillCastSecondEffect._astTargets.AddOneItem(stSkillTarget);

    //波及自身比较特殊还视为范围单体
    _stSkillCastSecondEffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_MAIN;
    _stSkillCastSecondEffect._chTargetFromPos = stRole.GetGridIndex();
    _stSkillCastSecondEffect._chTargetEndPos = stRole.GetGridIndex();

    return 0;
}

int CBattleRules::GetMinorMainInvoTarget(CBattleRole& stRole, CSkill& stSkill)
{
    CBattleSkillCastEffect& stMainCastSkill = _stSkillCastFirstEffect;
    CBattleSkillCastEffect& stMinorCastSkill = _stSkillCastSecondEffect;

    int iRet = stSkill.GetMinorSkillAffect(stMinorCastSkill._stSkillAffect);
    CT_RETURN(iRet);    

    CT_BATTLE(("确定波及主目标角色(%d)",
        stMainCastSkill._astTargets[0].GetID()));

    CBattleSkillTarget stSkillTarget(stMainCastSkill._astTargets[0].GetID());

    stMinorCastSkill._astTargets.AddOneItem(stSkillTarget);

    //波及主目标比较特殊还视为范围内波及
    stMinorCastSkill._chTargetType = VIDEO_EXE_SKILL_SCOPE_MAIN;
    stMinorCastSkill._chTargetFromPos = stMainCastSkill._chTargetFromPos;
    stMinorCastSkill._chTargetEndPos = stMainCastSkill._chTargetEndPos;

    return 0;
}

int CBattleRules::GetMinorBackInvoTarget(CBattleRole& stRole, CSkill& stSkill)
{
    int iRet = 0;

    stSkill.GetMinorSkillAffect(_stSkillCastSecondEffect._stSkillAffect);

    CSkillAffect& stMinorAffect = _stSkillCastSecondEffect._stSkillAffect;

    CT_BATTLE(("开始查找波及身后距离目标,波及距离(%d)",
        stMinorAffect.GetEffectRange()));

    CBattleRole& stMainTarget = BATTLE_INF->_pstRoles->GetRole(
        _stSkillCastFirstEffect._astTargets[0].GetID());

    bool bLeftSide = stRole.IsLeft();
    CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

    int iRange = stMinorAffect.GetEffectRange();
    if (iRange < 0) {iRange = 0;}

    int iSrcPos = stMainTarget.GetRelatGridIndex(bLeftSide);
    int iDstPos = stMainTarget.GetRelatGridIndex(bLeftSide);

    if (_stSkillCastFirstEffect._stSkillAffect.IsToEnemy())
    {
        iDstPos += iRange;
        if (iDstPos >= MAX_BATTLE_GRIDS)
        {
            iDstPos = MAX_BATTLE_GRIDS - 1;
        }
    }
    else
    {
        iDstPos -= iRange;
        if (iDstPos < 0)
        {
            iDstPos = 0;
        }
    }

    if (iDstPos < iSrcPos)
    {
        int iTmp = iSrcPos;
        iSrcPos = iDstPos;
        iDstPos = iTmp;
    }

    MAP_GRID_MULTI stMapGridMulti;
    iRet = stMapSide.GetDistanceSideRoles(iSrcPos, iDstPos, stMapGridMulti,
                stMainTarget.IsLeft());
    CT_RETURN(iRet);

    for (int i = 0; i < stMapGridMulti.Size(); ++i)
    {
        if (stMapGridMulti[i].GetRoleID() != stMainTarget.GetRoleID())
        {
            CT_BATTLE(("确定波及身后距离目标角色(%d)",
                       stMapGridMulti[i].GetRoleID()));
            CBattleSkillTarget stSkillTarget(stMapGridMulti[i].GetRoleID());
            _stSkillCastSecondEffect._astTargets.AddOneItem(stSkillTarget);
        }
    }

    if (_stSkillCastSecondEffect._astTargets.Size() > 0)
    {
        _stSkillCastSecondEffect._chTargetType =
            VIDEO_EXE_SKILL_DISTAN_GROUP;
        _stSkillCastSecondEffect._chTargetFromPos =
            bLeftSide ? iSrcPos : MAX_BATTLE_GRIDS - 1 - iSrcPos;
        _stSkillCastSecondEffect._chTargetEndPos =
            bLeftSide ? iDstPos : MAX_BATTLE_GRIDS - 1 - iDstPos;
    }

    return 0;
}

int CBattleRules::GetGroupTarget(CBattleRole& stRole, CSkill& stSkill,
        bool bToMainTarget)
{
    int iRet = 0;

    CBattleSkillCastEffect& stSkillAffect =
        (bToMainTarget ? _stSkillCastFirstEffect : _stSkillCastSecondEffect);
    iRet = stSkill.GetGroupSkillAffect(stSkillAffect._stSkillAffect,
        bToMainTarget);
    CT_RETURN(iRet); 

    bool bIsToEnemy =
        (bToMainTarget ? stSkill.IsMainToEnemy() : stSkill.IsMinorToEnemy());

    int iSrcPos = 0;
    int iDstPos = 0;

    bool bLeftSide = stRole.IsLeft();
    CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

    MAP_GRID_MULTI stMapGridMulti;

    CT_BATTLE(("群攻效果目标类型(%d)",
        stSkillAffect._stSkillAffect.GetTargetType()));
    switch(stSkillAffect._stSkillAffect.GetTargetType())
    {
    case CSkillAffect::SKILL_TARGET_ALL_ROLE:
        {
            if (bIsToEnemy)
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightFrontTo(),
                    MAX_BATTLE_GRIDS - 1, stMapGridMulti);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = MAX_BATTLE_GRIDS - 1;
            }
            else
            {
                iRet = stMapSide.GetDistanceRoles(0, stMapSide.GetLeftFrontTo(),
                    stMapGridMulti);
                iSrcPos = 0;
                iDstPos = stMapSide.GetLeftFrontTo();
            }
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_ALL_FRONT:
        if (bIsToEnemy)
        {
            if (stMapSide.GetRightBackTo() > stMapSide.GetRightFrontTo())
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightFrontTo(),
                    stMapSide.GetRightBackTo() - 1, stMapGridMulti);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = stMapSide.GetRightBackTo() - 1;
            }
            else
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightFrontTo(),
                    stMapSide.GetRightBackTo(), stMapGridMulti);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = stMapSide.GetRightBackTo();
            }
        }
        else
        {
            if (stMapSide.GetLeftBackTo() < stMapSide.GetLeftFrontTo())
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetLeftBackTo() + 1,
                    stMapSide.GetLeftFrontTo(), stMapGridMulti);
                iSrcPos = stMapSide.GetLeftBackTo() + 1;
                iDstPos = stMapSide.GetLeftFrontTo();
            }
            else
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetLeftBackTo(),
                    stMapSide.GetLeftFrontTo(), stMapGridMulti);
                iSrcPos = stMapSide.GetLeftBackTo();
                iDstPos = stMapSide.GetLeftFrontTo();
            }
        }
        CT_RETURN(iRet);
        break;
    case CSkillAffect::SKILL_TARGET_ALL_BACK://如果后场没有目标则查找前场
        if (bIsToEnemy)
        {
            iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightBackTo(),
                MAX_BATTLE_GRIDS - 1, stMapGridMulti);
            CT_RETURN(iRet);
            iSrcPos = stMapSide.GetRightBackTo();
            iDstPos = MAX_BATTLE_GRIDS - 1;
            if (stMapGridMulti.Size() <= 0)
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetRightFrontTo(),
                    stMapSide.GetRightBackTo(), stMapGridMulti);
                CT_RETURN(iRet);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = stMapSide.GetRightBackTo();
            }
        }
        else
        {
            iRet = stMapSide.GetDistanceRoles(0, stMapSide.GetLeftBackTo(),
                stMapGridMulti);
            CT_RETURN(iRet);
            iSrcPos = 0;
            iDstPos = stMapSide.GetLeftBackTo();
            if (stMapGridMulti.Size() <= 0)
            {
                iRet = stMapSide.GetDistanceRoles(stMapSide.GetLeftBackTo(),
                    stMapSide.GetLeftFrontTo(), stMapGridMulti);
                CT_RETURN(iRet);
                iSrcPos = stMapSide.GetLeftBackTo();
                iDstPos = stMapSide.GetLeftFrontTo();
            }
        }
        break;
    case CSkillAffect::SKILL_TARGET_PLAYER:
        {
            if (bIsToEnemy)
            {
                iRet = stMapSide.GetDistancePlayer(stMapSide.GetRightFrontTo(),
                    MAX_BATTLE_GRIDS - 1, stMapGridMulti);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = MAX_BATTLE_GRIDS - 1;
            }
            else
            {
                iRet = stMapSide.GetDistancePlayer(0,
                    stMapSide.GetLeftFrontTo(), stMapGridMulti);
                iSrcPos = 0;
                iDstPos = stMapSide.GetLeftFrontTo();
            }
            CT_RETURN(iRet);
        }
        break;
    case CSkillAffect::SKILL_TARGET_PARTNER:
        {
            if (bIsToEnemy)
            {
                iRet = stMapSide.GetDistancePartner(stMapSide.GetRightFrontTo(),
                    MAX_BATTLE_GRIDS - 1, stMapGridMulti);
                iSrcPos = stMapSide.GetRightFrontTo();
                iDstPos = MAX_BATTLE_GRIDS - 1;
            }
            else
            {
                iRet = stMapSide.GetDistancePartner(0,
                    stMapSide.GetLeftFrontTo(), stMapGridMulti);
                iSrcPos = 0;
                iDstPos = stMapSide.GetLeftFrontTo();
            }
            CT_RETURN(iRet);
        }
        break;
    default:
        break;
    }

    CT_BATTLE(("群体目标总数(%d) 是否主群攻(%d)",
        stMapGridMulti.Size(),bToMainTarget));

    for (int i = 0; i < stMapGridMulti.Size(); ++i)
    {
        CT_BATTLE(("群体目标角色(%d)",stMapGridMulti[i].GetRoleID()));
        CBattleSkillTarget stSkillTarget(stMapGridMulti[i].GetRoleID());
        stSkillAffect._astTargets.AddOneItem(stSkillTarget);
    }

    if (stSkillAffect._astTargets.Size() > 0)
    {
        stSkillAffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_MAIN;
        if (stSkillAffect._astTargets.Size() >= 2)
        {
            stSkillAffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_GROUP;
        }

        stSkillAffect._chTargetFromPos = bLeftSide ? iSrcPos : MAX_BATTLE_GRIDS - 1 - iSrcPos;
        stSkillAffect._chTargetEndPos = bLeftSide ? iDstPos : MAX_BATTLE_GRIDS - 1 - iDstPos;

        //群攻只设置第一个作为当前受击者
        SetNowTarget(stSkillAffect._astTargets[0].GetID()); //设置当前受击者ID
    }

    return 0;
}

int CBattleRules::CastSkill(CBattleRole& stRole, CSkill& stSkill, int iMainTargetID)
{
    int iRet = 0;
    
    if (stSkill.MainSkillHasMainTargetStru())
    {
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iMainTargetID);
        bool bLeftSide = stRole.IsLeft();

        CT_BATTLE(("施法者相对站位(%d)", stRole.GetRelatGridIndex(bLeftSide)));
        CT_BATTLE(("受击者相对站位(%d)", stTargetRole.GetRelatGridIndex(bLeftSide)));

        int iDistance = stTargetRole.GetRelatGridIndex(bLeftSide) - stRole.GetRelatGridIndex(bLeftSide);

        CT_BATTLE(("施法者与受击者的距离是(%d)", iDistance));
        if (0 == iDistance)
        {
            return 0;//对站在同一个格子的自己或者队友攻击 不需要移动
        }

        CSkillAffect stMainSkillAffect;//采用临时变量可以用在反击计算
        iRet = stSkill.GetMainSkillAffect(stMainSkillAffect);
        CT_RETURN(iRet);

        int iMaxAtkDist = stMainSkillAffect.GetMaxAtkDistance();
        int iRecommendDist = stMainSkillAffect.GetRecommendDistance();
        iMaxAtkDist = iMaxAtkDist < 0 ? 0 : iMaxAtkDist;
        iRecommendDist = iRecommendDist < 0 ? 0 : iRecommendDist;
        iRecommendDist = iRecommendDist > iMaxAtkDist ? iMaxAtkDist : iRecommendDist;

        CT_BATTLE(("技能最大攻击距离是(%d)，推荐攻击距离是(%d)",iMaxAtkDist,iRecommendDist));

        CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

        int iDstGrid = 0;
        if (iDistance > iMaxAtkDist)
        {
            //主目标选择时候考虑最远只能相邻对方前场
            iDstGrid = stRole.GetRelatGridIndex(bLeftSide) + iDistance - iMaxAtkDist;
            iDstGrid = CT_MIN(stMapSide.GetRightFrontTo() - 1, iDstGrid);
            iDstGrid = CT_MAX(0, iDstGrid);

            CT_BATTLE(("角色(%d)当前相对格子(%d)移动到格子(%d)对方前场(%d)",
                        stRole.GetRoleID(),stRole.GetRelatGridIndex(bLeftSide),iDstGrid,
                        stMapSide.GetRightFrontTo()));
            iRet = RoleMoveTo(stRole, iDstGrid, true);
            CT_RETURN(iRet);
        }
        else if (iDistance > 0 && iDistance < iRecommendDist)
        {
            //主目标选择时候没有考虑推荐距离
            iDstGrid = stRole.GetRelatGridIndex(bLeftSide) + iDistance - iRecommendDist;
            iDstGrid = CT_MAX(0, iDstGrid);

            CT_BATTLE(("目标在攻击范围内，施法者朝推荐地图格(%d)移动", iDstGrid));
            iRet = RoleMoveTo(stRole, iDstGrid, true);
            CT_RETURN(iRet);
        }
        else
        {
            CT_BATTLE(("目标在攻击范围内，不需要做移动"));
        }
    }

    return 0;
}

int CBattleRules::RoleMoveTo(CBattleRole& stRole, int iDstGrid, bool bNeedRecord)
{
    bool bLeftSide = stRole.IsLeft();
    int iSrcGrid = stRole.GetRelatGridIndex(bLeftSide);
    int iRet = BATTLE_INF->_pstMap->MoveTo(stRole.GetRoleID(), iSrcGrid, iDstGrid, bLeftSide, bNeedRecord);
    CT_RETURN(iRet);
    
    return 0;
}

int CBattleRules::SkillPreEffectDataCalc(int& iPreData, int iBase, CSkillEffect& stSkillEffect, int iMulti)
{
    int64 i64Value = 0;
    int iData = stSkillEffect.GetData();
    if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_NUM))
    {
        iPreData += (iData * iMulti);
    }
    else if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_RATE))
    {
        i64Value = INT64_1 * iBase * iData * iMulti;
        i64Value /= BATTLE_RATE_SKILL_PERCENT;
        iPreData += (int)i64Value;
    }

    //注意不能在这里修正iPreData为非负 因为有可能是扣血、勇气、怒气

    return 0;
}

int CBattleRules::CastSkillEffectAttr(CBattleRole& stRole)
{
    //注意：施法者及受击者需且仅需计算一次
    bool abHasInit[MAX_BATTLE_ROLES];
    for (int i = 0; i < MAX_BATTLE_ROLES; ++i)
    {
        abHasInit[i] = false;
    }

    int iRet = 0;

    //施法者
    iRet = stRole.CalcBuffAddAttr(stRole.GetTurnMainAttr());
    CT_RETURN(iRet);

    iRet = stRole.CalcBuffAddAttr(stRole.GetTurnMinorAttr());
    CT_RETURN(iRet);

    abHasInit[stRole.GetRoleID()] = true;//战场ID即下标

    //受击者
    int iRoleID = 0;
    for (int i = 0; i < _stSkillCastFirstEffect._astTargets.Size(); ++i)
    {
        iRoleID = _stSkillCastFirstEffect._astTargets[i].GetID();
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
        if (!abHasInit[stTargetRole.GetRoleID()])
        {
            iRet = stTargetRole.CalcBuffAddAttr(stTargetRole.GetTurnMainAttr());
            CT_RETURN(iRet);
            abHasInit[stTargetRole.GetRoleID()] = true;//战场ID即下标
        }
    }

    for (int i = 0; i < _stSkillCastSecondEffect._astTargets.Size(); ++i)
    {
        iRoleID = _stSkillCastSecondEffect._astTargets[i].GetID();
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
        if (!abHasInit[stTargetRole.GetRoleID()])
        {
            iRet =
                stTargetRole.CalcBuffAddAttr(stTargetRole.GetTurnMinorAttr());
            CT_RETURN(iRet);
            abHasInit[stTargetRole.GetRoleID()] = true;//战场ID即下标
        }
    }

    return 0;
}

int CBattleRules::SkillPreEffectData(CBattleRole& stRole, bool bIsFirst, CSkillEffect& stSkillEffect)
{
    CPlayerAttr& stPreAttr = (bIsFirst ? stRole._stTurnMainAttr : stRole._stTurnMinorAttr);
    unsigned char ucSubType = stSkillEffect.GetSubType();
    int iPreData = stPreAttr.GetAttr(ucSubType);
    SkillPreEffectDataCalc(iPreData, stRole.GetTypeAttr(ucSubType), stSkillEffect);
    stPreAttr.SetAttr(ucSubType, iPreData);

    return 0;
}

int CBattleRules::CastSkillPreEffect(CBattleRole& stRole, bool bIsFirst)
{
    int iRet = 0;
    int iRoleID = 0;

    CBattleSkillCastEffect& stSkillCastEffect = (bIsFirst ? _stSkillCastFirstEffect : _stSkillCastSecondEffect);

    for (int i = 0; i < stSkillCastEffect._stSkillAffect.GetSkillEffectSize(); ++i)
    {
        CSkillEffect& stSkillEffect =
            stSkillCastEffect._stSkillAffect.GetSkillEffect(i);

        if (CSkillEffect::SKILL_STAT_PRE_CASTER == stSkillEffect.GetStatType())
        {
            //施法者回合数据加成
            iRet = SkillPreEffectData(stRole, bIsFirst, stSkillEffect);
            CT_RETURN(iRet);
        }
        else if (CSkillEffect::SKILL_STAT_PRE_TARGET == stSkillEffect.GetStatType())
        {
            for (int j = 0; j < stSkillCastEffect._astTargets.Size(); ++j)
            {
                iRoleID = stSkillCastEffect._astTargets[j].GetID();
                if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
                {
                    continue;
                }
                //受击者回合数据加成
                CBattleRole& stTargetRole =
                    BATTLE_INF->_pstRoles->GetRole(iRoleID);

                iRet = SkillPreEffectData(stTargetRole, bIsFirst, stSkillEffect);
                CT_RETURN(iRet);
            }
        }
    }

    return 0;
}

int CBattleRules::CastSkillEffect(CBattleRole& stRole, CSkill& stSkill)
{
    int iRet = 0;

    SetRuleStat(BATTLE_RULE_STAT_MAIN_DO);//主目标计算阶段

    //技能消耗
    iRet = stRole.CastSkill(stSkill);
    CT_RETURN(iRet);

    //状态处理 STATUS_TRIGGER_TURN_ACTION //回合行动时触发 攻击者移动后 发出技能效果前
    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
         CStatusMgr::STATUS_TRIGGER_TURN_ACTION, 0);

    //状态处理 STATUS_TRIGGER_TURN_ACT_OBJ_LIMIT //回合行动时触发 攻击者移动后 发出技能效果前 要求检查目标临界值
    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
         CStatusMgr::STATUS_TRIGGER_TURN_ACT_OBJ_LIMIT,
         CSkillEffect::SKILL_SUB_STAT_HP, 0);

    //记录技能释放
    BATTLE_INF->_pstVideo->CastSkill(stRole.GetRoleID(), _stCastSkill.GetID(),
        _stCastSkill.GetTargetType(), _stSkillCastFirstEffect,
        _stSkillCastSecondEffect);

    //检查命中
    CT_BATTLE(("主目标或者群体目标命中"));
    iRet = CastSkillEffectHitRateCheck(stRole, _stSkillCastFirstEffect, true);
    CT_RETURN(iRet);

    CT_BATTLE(("波及目标或者群体目标命中"));
    iRet = CastSkillEffectHitRateCheck(stRole, _stSkillCastSecondEffect, false);
    CT_RETURN(iRet);

    //格档
    CT_BATTLE(("主目标或者群体目标格档"));
    iRet = CastSkillEffectBlockCheck(stRole, _stSkillCastFirstEffect, true);
    CT_RETURN(iRet);
    CT_BATTLE(("波及目标或者群体目标格档"));
    iRet = CastSkillEffectBlockCheck(stRole, _stSkillCastSecondEffect, false);
    CT_RETURN(iRet);

    //击飞
    CT_BATTLE(("主目标或者群体目标击飞"));
    iRet = CastSkillEffectHitBackCheck(stRole, _stSkillCastFirstEffect);
    CT_RETURN(iRet);
    CT_BATTLE(("波及目标或者群体目标击飞"));
    iRet = CastSkillEffectHitBackCheck(stRole, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    //拖拽
    CT_BATTLE(("主目标或者群体目标拖拽"));
    iRet = CastSkillEffectPullCheck(stRole, _stSkillCastFirstEffect);
    CT_RETURN(iRet);
    CT_BATTLE(("波及目标或者群体目标拖拽"));
    iRet = CastSkillEffectPullCheck(stRole, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    SetRuleStat(BATTLE_RULE_STAT_MAIN_DO);//主目标计算阶段

    ClearSkillDead();
    ClearSkillRandom();

    //战斗伤害计算2
    CT_BATTLE(("战斗伤害计算2"));
    iRet = SkillEffect2(stRole, stSkill, _stSkillCastFirstEffect, true);
    CT_RETURN(iRet);

    SetRuleStat(BATTLE_RULE_STAT_MINOR_DO);//辅目标计算阶段

    iRet = SkillEffect2(stRole, stSkill, _stSkillCastSecondEffect, false);
    CT_RETURN(iRet);

    bool bHasHitEnemy = false;
    if ((stSkill.IsMainToEnemy()
            && _stSkillCastFirstEffect._astTargets.Size() > 0) 
            ||
        (stSkill.IsMinorToEnemy()
            && _stSkillCastSecondEffect._astTargets.Size() > 0))
    {
        bHasHitEnemy = true;
    }

    VideoAllSkillRoleDead();//同一个技能统一输出死亡

    SetRuleStat(BATTLE_RULE_STAT_HIT_BACK);//目标反击计算阶段

    //战斗伤害计算3
    CT_BATTLE(("反击伤害计算"));
    iRet = SkillEffect3(stRole, stSkill, _stSkillCastFirstEffect);
    CT_RETURN(iRet);

    SetRuleStat(BATTLE_RULE_STAT_FALL_BACK);//目标撤退计算阶段

    //战斗计算4
    CT_BATTLE(("战斗伤害计算4"));
    iRet = SkillEffect4(stRole, stSkill, _stSkillCastFirstEffect);
    CT_RETURN(iRet);

    iRet = SkillEffect4(stRole, stSkill, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    //状态处理 STATUS_TRIGGER_TURN_OVER //回合行动结束时触发 +
    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
         CStatusMgr::STATUS_TRIGGER_TURN_OVER, 0);

    if (bHasHitEnemy)
    {
        //状态处理 STATUS_TRIGGER_TURN_OVER_AND_HIT //回合行动结束时触发 有命中目标+
        CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
            CStatusMgr::STATUS_TRIGGER_TURN_OVER_AND_HIT, 0);
    }

    SetRuleStat(BATTLE_RULE_STAT_FINISH);//战斗结束阶段

    return 0;
}

int CBattleRules::CastSkillEffectHitRateCheck(CBattleRole& stRole,
        CBattleSkillCastEffect& stSkillCastEffect, bool bIsFirst)
{
    CT_BATTLE(("潜在目标总数(%d)", stSkillCastEffect._astTargets.Size()));

    if (stSkillCastEffect._astTargets.Size() <= 0)
    {
        return 0;
    }

    if (stSkillCastEffect.IsToEnemy())
    {
        if (BATTLE_RULE_STAT_PRE_SKILL == GetRuleStat())
        {
           CT_BATTLE(("预执行技能阶段,不检查命中率,必命中!"));
           for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
           {
               stSkillCastEffect._astTargets[i].SetHitted();
           }
           return 0;
        }

        int iAHit = 0;
        int iBDodge = 0;
        int iRoleID = 0;
        for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
        {
            iRoleID = stSkillCastEffect._astTargets[i].GetID();
            CT_BATTLE(("检查角色(%d)",iRoleID));

            if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
            {
                continue;
            }

            CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

            iAHit = stRole.GetTypeAttr(EXT_ATTR_HIT, bIsFirst);
            iBDodge = stTargetRole.GetTypeAttr(EXT_ATTR_DODGE, bIsFirst);
            if (iAHit < 0){iAHit = 0;}
            if (iBDodge < 0){iBDodge = 0;}
            CT_BATTLE(("A命中等级(%d)",iAHit));
            CT_BATTLE(("B闪避等级(%d)",iBDodge));

#define HIT_DODGE_MACRO_1 0.42
#define HIT_DODGE_MACRO_2 100.0
#define HIT_DODGE_MACRO_3 7.0
#define HIT_DODGE_MACRO_4 3
#define HIT_DODGE_MACRO_5 800

            double dHitDodge = 0.0;
            if (iAHit >= iBDodge)
            {
                dHitDodge = (iAHit - iBDodge) * 1.0;
                dHitDodge = (pow(dHitDodge, (double)HIT_DODGE_MACRO_1) * HIT_DODGE_MACRO_2) / (double)HIT_DODGE_MACRO_3;

                CT_BATTLE(("修正后命中闪避(%0.2lf) = [(A总命中等级(%d)-B总闪避等级(%d))^(%f)]*(%f)/(%f)",
                            dHitDodge,iAHit,iBDodge,HIT_DODGE_MACRO_1,HIT_DODGE_MACRO_2,HIT_DODGE_MACRO_3));
            }
            else
            {
                dHitDodge = (iBDodge - iAHit) * 1.0;
                dHitDodge = (-1) * ((pow(dHitDodge, (double)HIT_DODGE_MACRO_1) * HIT_DODGE_MACRO_2) / (double)HIT_DODGE_MACRO_3);

                CT_BATTLE(("修正后命中闪避(%0.2lf) = (-1) * ([(B总闪避等级(%d)-A总命中等级(%d))^(%f)]*(%f)/(%f))",
                            dHitDodge,iBDodge,iAHit,HIT_DODGE_MACRO_1,HIT_DODGE_MACRO_2,HIT_DODGE_MACRO_3));
            }

            int iHitRate = HIT_DODGE_MACRO_5 + (stRole.GetLevel()-stTargetRole.GetLevel()) * HIT_DODGE_MACRO_4 + (int)dHitDodge;
            CT_BATTLE(("最终命中率(%d) = %d + (A等级(%d)-B等级(%d)) * (%d) + 修正后命中闪避(%0.2lf)",
                        iHitRate,HIT_DODGE_MACRO_5,stRole.GetLevel(),stTargetRole.GetLevel(),HIT_DODGE_MACRO_4,dHitDodge));

            if (iHitRate < BATTLE_RATE_HIT_AMEND_MIN)
            {
                iHitRate = BATTLE_RATE_HIT_AMEND_MIN;
                CT_BATTLE(("最终命中率强制修正为(%d)!",iHitRate));
            }

            int iRand = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
            if (iRand > iHitRate)
            {
                CT_BATTLE(("概率(%d)结果：没有命中!", iRand));
                stSkillCastEffect._astTargets[i].SetNotHitted();
            }
            else
            {
                CT_BATTLE(("概率(%d)结果：成功命中!", iRand));
                stSkillCastEffect._astTargets[i].SetHitted();
            }
        }
    }
    else
    {
        CT_BATTLE(("非敌技能功能,不检查命中率,必命中!"));
        for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
        {
            CT_BATTLE(("命中友方角色(%d)",
                stSkillCastEffect._astTargets[i].GetID()));
            stSkillCastEffect._astTargets[i].SetHitted();
        }
    }

    return 0;
}

int CBattleRules::CastSkillEffectBlockCheck(CBattleRole& stRole,
        CBattleSkillCastEffect& stSkillCastEffect, bool bIsFirst)
{
    CT_BATTLE(("潜在目标总数(%d)", stSkillCastEffect._astTargets.Size()));

    if (stSkillCastEffect._astTargets.Size() <= 0)
    {
        return 0;
    }

    int iRoleID = 0;
    if (stSkillCastEffect.IsToEnemy())
    {
        int iABlow = 0;
        int iBBlock = 0;
        for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
        {
            iRoleID = stSkillCastEffect._astTargets[i].GetID();
            if (!stSkillCastEffect._astTargets[i].IsHitted())
            {
                CT_BATTLE(("未命中角色(%d) 跳过检查",iRoleID));
                continue;
            }
            CT_BATTLE(("检查角色(%d)",iRoleID));

            if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
            {
                continue;
            }
            CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
            if (stTargetRole.IsSwim())
            {
                CT_BATTLE(("角色(%d)眩晕 不能格挡",
                    stSkillCastEffect._astTargets[i].GetID()));
                continue;
            }

            iABlow = stRole.GetTypeAttr(EXT_ATTR_ANTI_BLOCK, bIsFirst);
            iBBlock = stTargetRole.GetTypeAttr(EXT_ATTR_BLOCK, bIsFirst);
            if (iABlow < 0){iABlow = 0;}
            if (iBBlock < 0){iBBlock = 0;}
            CT_BATTLE(("A破击等级(%d)",iABlow));
            CT_BATTLE(("B格挡等级(%d)",iBBlock));

#define BLOW_BLOCK_MACRO_1 0.45
#define BLOW_BLOCK_MACRO_2 50.0
#define BLOW_BLOCK_MACRO_3 3.0
#define BLOW_BLOCK_MACRO_4 4
#define BLOW_BLOCK_MACRO_5 700

            double dBlowBlock = 0.0;
            if (iABlow >= iBBlock)
            {
                dBlowBlock = (iABlow - iBBlock) * 1.0;
                dBlowBlock = (pow(dBlowBlock, (double)BLOW_BLOCK_MACRO_1) * BLOW_BLOCK_MACRO_2) / (double)BLOW_BLOCK_MACRO_3;

                CT_BATTLE(("修正后破击格挡(%0.2lf) = [(A总破击等级(%d)-B总格挡等级(%d))^(%f)]*(%f)/(%f)",
                            dBlowBlock,iABlow,iBBlock,BLOW_BLOCK_MACRO_1,BLOW_BLOCK_MACRO_2,BLOW_BLOCK_MACRO_3));
            }
            else
            {
                dBlowBlock = (iBBlock - iABlow) * 1.0;
                dBlowBlock = (-1) * (pow(dBlowBlock, (double)BLOW_BLOCK_MACRO_1) * BLOW_BLOCK_MACRO_2) / (double)BLOW_BLOCK_MACRO_3;

                CT_BATTLE(("修正后破击格挡(%0.2lf) = (-1) * [(B总格挡等级(%d)-A总破击等级(%d))^(%f)]*(%f)/(%f)",
                            dBlowBlock,iBBlock,iABlow,BLOW_BLOCK_MACRO_1,BLOW_BLOCK_MACRO_2,BLOW_BLOCK_MACRO_3));
            }

            int iBlowRate = BLOW_BLOCK_MACRO_5 + (stRole.GetLevel()-stTargetRole.GetLevel()) * BLOW_BLOCK_MACRO_4 + (int)dBlowBlock;
            CT_BATTLE(("最终破击率(%d) = %d + (A等级(%d)-B等级(%d)) * (%d) + 修正后破击格挡(%0.2lf)",
                        iBlowRate,BLOW_BLOCK_MACRO_5,stRole.GetLevel(),stTargetRole.GetLevel(),BLOW_BLOCK_MACRO_4,dBlowBlock));

            if (iBlowRate < BATTLE_RATE_BLOW_AMEND_MIN)
            {
                iBlowRate = BATTLE_RATE_BLOW_AMEND_MIN;
                CT_BATTLE(("最终破击率强制修正为(%d)!",iBlowRate));
            }

            int iRand = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
            if (iRand < iBlowRate)
            {
                CT_BATTLE(("概率(%d)结果：没有格挡!",iRand));
                stSkillCastEffect._astTargets[i].SetNotBlock();
            }
            else
            {
                CT_BATTLE(("概率(%d)结果：成功格挡!",iRand));
                stSkillCastEffect._astTargets[i].SetBlock();
            }
        }
    }
    else
    {
        CT_BATTLE(("非敌技能功能,不检查格挡率,必破击!"));
        for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
        {
            CT_BATTLE(("友方角色(%d)没有格挡",
                stSkillCastEffect._astTargets[i].GetID()));
            stSkillCastEffect._astTargets[i].SetNotBlock();
        }
    }

    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        iRoleID = stSkillCastEffect._astTargets[i].GetID();
        if (!stSkillCastEffect._astTargets[i].IsBlock())
        {
            continue;
        }
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

        //状态处理 STATUS_TRIGGER_BLOCK_ATK_BEFORE //格挡攻击时触发 计算伤害之前+
        CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
            CStatusMgr::STATUS_TRIGGER_BLOCK_ATK_BEFORE, 0);
    }

    return 0;
}

int CBattleRules::CastSkillEffectHitBackCheck(CBattleRole& stRole,
        CBattleSkillCastEffect& stSkillCastEffect)
{
    int iRet = 0;
    CSkillEffect stHitBackEffect;
    bool bHasHitBackEffect;

    iRet = stSkillCastEffect._stSkillAffect.GetHitBackEffect(bHasHitBackEffect,
        stHitBackEffect);
    CT_RETURN(iRet);

    if (!bHasHitBackEffect)
    {
        CT_BATTLE(("技能没有配置击飞效果"));
        return 0;
    }

    CT_BATTLE(("潜在目标总数(%d)", stSkillCastEffect._astTargets.Size()));
    int iRoleID = 0;
    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        iRoleID = stSkillCastEffect._astTargets[i].GetID();
        if (!stSkillCastEffect._astTargets[i].IsHitted())
        {
            CT_BATTLE(("未命中角色(%d) 跳过检查",iRoleID));
            continue;
        }

        CT_BATTLE(("击飞率(%d)检查角色(%d)",stHitBackEffect.GetTriggerRate(),
            iRoleID));

        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

        int iRand = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
        if (iRand >= stHitBackEffect.GetTriggerRate())
        {
            CT_BATTLE(("概率(%d)结果：没有击飞!",iRand));
            stSkillCastEffect._astTargets[i].SetHitBackDistance(0);
        }
        else
        {
            //需要判断是否有免疫击飞的BUFF
            if (stTargetRole.InDefinitBuff(CSkillEffect::SKILL_STAT_IMMUNE_MAIN,
                    CSkillEffect::SKILL_STAT_HITBACK))
            {
                CT_BATTLE(("概率(%d)结果：目标免疫击飞!",iRand));
                stSkillCastEffect._astTargets[i].SetHitBackDistance(0);
                continue;
            }

            CT_BATTLE(("概率(%d)结果：击飞距离(%d)!",iRand,
                stHitBackEffect.GetData()));
            stSkillCastEffect._astTargets[i].SetHitBackDistance(
                stHitBackEffect.GetData());
        }
    }

    return 0;
}

int CBattleRules::CastSkillEffectPullCheck(CBattleRole& stRole,
        CBattleSkillCastEffect& stSkillCastEffect)
{
    int iRet = 0;
    CSkillEffect stPullEffect;
    bool bHasPullEffect;

    iRet = stSkillCastEffect._stSkillAffect.GetPullEffect(bHasPullEffect,
        stPullEffect);
    CT_RETURN(iRet);

    if (!bHasPullEffect)
    {
        CT_BATTLE(("技能没有配置拖拽效果"));
        return 0;
    }

    CT_BATTLE(("潜在目标总数(%d)", stSkillCastEffect._astTargets.Size()));
    int iRoleID = 0;
    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        iRoleID = stSkillCastEffect._astTargets[i].GetID();
        if (!stSkillCastEffect._astTargets[i].IsHitted())
        {
            CT_BATTLE(("未命中角色(%d) 跳过检查",iRoleID));
            continue;
        }

        CT_BATTLE(("拖拽率(%d)检查角色(%d)",stPullEffect.GetTriggerRate(),
            iRoleID));

        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

        int iRand = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
        if (iRand >= stPullEffect.GetTriggerRate())
        {
            CT_BATTLE(("概率(%d)结果：没有拖拽!",iRand));
            stSkillCastEffect._astTargets[i].SetPullDistance(0);
        }
        else
        {
            //需要判断是否有免疫拖拽的BUFF
            if (stTargetRole.InDefinitBuff(CSkillEffect::SKILL_STAT_IMMUNE_MAIN,
                    CSkillEffect::SKILL_STAT_PULL))
            {
                CT_BATTLE(("概率(%d)结果：目标免疫拖拽!",iRand));
                stSkillCastEffect._astTargets[i].SetPullDistance(0);
                continue;
            }

            CT_BATTLE(("概率(%d)结果：拖拽距离(%d)!",iRand,
                stPullEffect.GetData()));
            stSkillCastEffect._astTargets[i].SetPullDistance(
                stPullEffect.GetData());
        }
    }

    return 0;
}

int CBattleRules::GetRelation(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget)
{
    if (stBattleRole.GetRoleID() == stBattleTarget.GetRoleID())
    {
        return CBattleBuffList::BATTLE_BUFF_SOURCE_SELF;
    }
    else if (stBattleRole.IsLeft() == stBattleTarget.IsLeft())
    {
        return CBattleBuffList::BATTLE_BUFF_SOURCE_TEAM;
    }
    else
    {
        return CBattleBuffList::BATTLE_BUFF_SOURCE_ENEMY;
    }
}

int CBattleRules::RolePreSkill(CBattleRole& stBattleRole)
{
    CRoleSkillList& stPreSkillList = stBattleRole.GetPreSkillList();

    int iIndex = 0;
    unsigned int uiSkillID = 0;

#ifdef _DEBUG
    CTSizeString<100> sVideo;
    for (int i = 0; i < stPreSkillList.GetSkillSize(); ++i)
    {
        CRoleSkillUnit& stPreSkillUnit = stPreSkillList.GetSkillUnit(i);
        sVideo.Cat("%u_%d ",
                   stPreSkillUnit.GetSkillID(),stPreSkillUnit.GetTurn());

    }
    CT_BATTLE(("角色(%d)预执行技能开始:数量(%d)序列(%s)",
               stBattleRole.GetRoleID(),stPreSkillList.GetSkillSize(),
               sVideo.Get()));
#endif

    for (int i = 0; i < stPreSkillList.GetSkillSize(); )//不要递增 放在逻辑里面
    {
        CRoleSkillUnit& stPreSkillUnit = stPreSkillList.GetSkillUnit(i);

        uiSkillID = stPreSkillUnit.GetSkillID();

        if (stBattleRole.HasDead())
        {
            CT_BATTLE(("角色(%d)已死亡免执行技能(%u)",stBattleRole.GetRoleID(),
                       uiSkillID));
            return 0;
        }

        iIndex = CMainCtrl::m_pstMain->m_stSkillMgr.FindSkillCfg(uiSkillID);
        if (iIndex < 0)
        {
            CT_ERROR(("battle id(%d) pre skill(%u) but not exist",
                      stBattleRole.GetRoleID(),uiSkillID));

            ++i;
        }

        CSkill& stSkill =
            CMainCtrl::m_pstMain->m_stSkillMgr.GetSkillCfg(iIndex);

        SetPreSkillSrcID(stPreSkillUnit.GetRoleID());

        RoleExecSkill(stBattleRole, stSkill);

        stPreSkillUnit.NewTurn();

        if (stPreSkillUnit.GetTurn() <= 0)
        {
            stPreSkillList.DelSkillUnit(i);
        }
        else
        {
            ++i;
        }
    }

    CT_BATTLE(("角色(%d)预执行技能结束",stBattleRole.GetRoleID()));

    return 0;
}

int CBattleRules::RoleExecSkill(CBattleRole& stBattleRole, CSkill& stSkill)
{
    CT_BATTLE(("角色(%d)执行技能(%u)",stBattleRole.GetRoleID(),
               stSkill.GetID()));

    int iSkillType = stSkill.GetType();
    if (!stSkill.IsValidType(iSkillType))
    {
        return ERROR_SKILL_ERROR_CFG;
    }

    //当前只处理普通技能
    if (!stSkill.IsNormalSkill())
    {
        CT_WARNING(("skill(%u) not normal skill won't exec",stSkill.GetID()));
        return 0;
    }

    if (!stBattleRole.CanCastNormalSkill())
    {
        CT_BATTLE(("角色(%d)不能释放技能(%d)", stBattleRole.GetRoleID(),
                    stSkill.GetID()));
        return 0;
    }

    int iRet = 0;

    SetSkillType(iSkillType);

    iRet = FindTargets(stBattleRole, stSkill);
    CT_RETURN(iRet);

    if (!IsFindMainTarget())
    {
        CT_BATTLE(("角色(%d)因没有目标而不能释放技能(%u)",
                   stBattleRole.GetRoleID(),stSkill.GetID()));
        return 0;
    }

    iRet = CastSkill(stBattleRole, stSkill,
        _stSkillCastFirstEffect._astTargets[0].GetID());
    CT_RETURN(iRet);

    iRet = stBattleRole.CastSkill(stSkill);
    CT_RETURN(iRet);
        
    //检查命中
    iRet = CastSkillEffectHitRateCheck(stBattleRole, _stSkillCastFirstEffect,
        true);
    CT_RETURN(iRet);

    iRet = CastSkillEffectHitRateCheck(stBattleRole, _stSkillCastSecondEffect,
        false);
    CT_RETURN(iRet);

    //格档
    iRet = CastSkillEffectBlockCheck(stBattleRole, _stSkillCastFirstEffect,
        true);
    CT_RETURN(iRet);

    iRet = CastSkillEffectBlockCheck(stBattleRole, _stSkillCastSecondEffect,
        false);
    CT_RETURN(iRet);

    //击飞
    iRet = CastSkillEffectHitBackCheck(stBattleRole, _stSkillCastFirstEffect);
    CT_RETURN(iRet);

    iRet = CastSkillEffectHitBackCheck(stBattleRole, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    //拖拽
    iRet = CastSkillEffectPullCheck(stBattleRole, _stSkillCastFirstEffect);
    CT_RETURN(iRet);

    iRet = CastSkillEffectPullCheck(stBattleRole, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    ClearSkillDead();
    ClearSkillRandom();

    //伤害计算
    iRet = SkillEffect2(stBattleRole, stSkill, _stSkillCastFirstEffect, true);
    CT_RETURN(iRet);

    iRet = SkillEffect2(stBattleRole, stSkill, _stSkillCastSecondEffect, false);
    CT_RETURN(iRet);

     VideoAllSkillRoleDead();//同一个技能统一输出死亡

    //撤退计算
    iRet = SkillEffect4(stBattleRole, stSkill, _stSkillCastFirstEffect);
    CT_RETURN(iRet);

    iRet = SkillEffect4(stBattleRole, stSkill, _stSkillCastSecondEffect);
    CT_RETURN(iRet);

    //恢复设置
    SetNowAttack(stBattleRole.GetRoleID()); //设置当前攻击者ID
    SetNowTarget(-1); //设置当前受击者ID

    return 0;
}

int CBattleRules::BattleReviseInit(CBattleRole& stBattleRole)
{
    int iIndex = 0;
    CBattleReviseUnit stReviseUnit;
    CStatusList& stStatusList = stBattleRole.GetStatusList();
    for (int i = 0; i < stStatusList._astStatus.Size(); ++i)
    {
        CStatusObj& stStatusObj = stStatusList._astStatus[i];
        iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindSkillEffect(
                    stStatusObj._iResID);
        if (iIndex < 0)
        {
            continue;
        }

        CSkillEffect& stSkillEffect =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetSkillEffect(iIndex);

        if (stStatusObj._iAddNum <= 1)//因为默认初始值就是1
        {
            continue;
        }

        if (CSkillEffect::SKILL_STAT_REVISE_VAL == stSkillEffect.GetStatType()
                ||
            CSkillEffect::SKILL_SUB_STAT_REVISE == stSkillEffect.GetSubType())
        {
            stReviseUnit.Clear();
            stReviseUnit.SetAddNum(stStatusObj._iAddNum - 1);
            stReviseUnit.SetEffectID(stSkillEffect.GetID());
            _stBattleReviseAtk.AddReviseUnit(stReviseUnit);
        }
    }
#ifdef _DEBUG
    CT_BATTLE(("角色(%d)行动开始修正伤害列表数量(%d)",stBattleRole.GetRoleID(),
               _stBattleReviseAtk.GetReviseUnitSize()));
    for (int i = 0; i < _stBattleReviseAtk.GetReviseUnitSize(); ++i)
    {
        CBattleReviseUnit& stReviseUnit = _stBattleReviseAtk.GetReviseUnit(i);
        CT_BATTLE(("修正伤害效果(%u)叠加层数(%d)",stReviseUnit.GetEffectID(),
                   stReviseUnit.GetAddNum()));
    }
#endif
    return 0;
}

int CBattleRules::ReviseAttackValue(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget)
{
    if (GetNowAttack() != stBattleRole.GetRoleID())
    {
        return 0;
    }

    int64& i64AtkValue = GetAtkValue();
    int iBaseAtk = (int)i64AtkValue;

    int iIndex = 0;
    int iChgValue = 0;

    CT_BATTLE(("修正前攻击伤害(%lld)",i64AtkValue));

    for (int i = 0; i < _stBattleReviseAtk.GetReviseUnitSize(); ++i)
    {
        CBattleReviseUnit& stReviseUnit = _stBattleReviseAtk.GetReviseUnit(i);

        if (stReviseUnit.GetTargetID() > 0
            && stBattleTarget.GetRoleID() != stReviseUnit.GetTargetID())
        {
            continue;
        }

        iIndex = CMainCtrl::m_pstMain->m_stSkillMgr.FindSkillEffCfg(
            stReviseUnit.GetEffectID());
        if (iIndex < 0)
        {
            CT_WARNING(("skill effect(%u) empty when role(%d) revise atk val",
                        stReviseUnit.GetEffectID(),stBattleRole.GetRoleID()));
            continue;
        }

        CSkillEffect& stSkillEffect =
            CMainCtrl::m_pstMain->m_stSkillMgr.GetSkillEffCfg(iIndex);

        iChgValue = 0;

        switch (stSkillEffect.GetStatType())
        {
        case CSkillEffect::SKILL_STAT_REVISE_VAL:
            {
                switch (stSkillEffect.GetSubType())
                {
                case CSkillEffect::SKILL_SUB_STAT_ANGER://怒气
                    {
                        if (stReviseUnit.GetAddNum() <= 0)
                        {
                            CT_BATTLE(("角色(%u)怒气修正伤害,叠加层数(%d)",
                                stBattleRole.GetRoleID(),
                                stReviseUnit.GetAddNum()));
                            break;
                        }
                
                        SkillPreEffectDataCalc(iChgValue, iBaseAtk,
                            stSkillEffect, stReviseUnit.GetAddNum());
                
                        i64AtkValue += iChgValue;
                
                        CT_BATTLE(("修正后伤害(%lld) ChgValue(%d) 怒气倍率(%d)",
                            i64AtkValue,iChgValue,stReviseUnit.GetAddNum()));
                    }
                    break;

                case CSkillEffect::SKILL_SUB_STAT_DISTANCE://站位距离
                    {
                        int iDistance = stBattleRole.GetGridIndex() -
                                stBattleTarget.GetGridIndex();
                        if (iDistance < 0)
                        {
                            iDistance = 0 - iDistance;
                        }
                        if (iDistance < stReviseUnit.GetAddNum())
                        {
                            iDistance = stReviseUnit.GetAddNum();
                        }
                        if (iDistance <= 0)
                        {
                            CT_BATTLE(("角色(%u)站位距离修正伤害,叠加层数(%d)",
                                stBattleRole.GetRoleID(),iDistance));
                            break;
                        }
                
                        SkillPreEffectDataCalc(iChgValue, iBaseAtk,
                            stSkillEffect, iDistance);
                
                        i64AtkValue += iChgValue;
                
                        CT_BATTLE(("修正后伤害(%lld) ChgValue(%d) 站位距离(%d)",
                            i64AtkValue,iChgValue,iDistance));
                    }
                    break;

                //下一次行动开始且整个战斗都生效的修正伤害
                case CSkillEffect::SKILL_SUB_STAT_REVISE:
                //只是当回合生效的伤害修正 aux_data特定目标
                case CSkillEffect::SKILL_SUB_STAT_REVISE_OBJECT:
                    {
                        if (stReviseUnit.GetAddNum() <= 0)
                        {
                            CT_BATTLE(("角色(%u)次行动修正伤害,叠加层数(%d)",
                                stBattleRole.GetRoleID(),
                                stReviseUnit.GetAddNum()));
                            break;
                        }
                
                        SkillPreEffectDataCalc(iChgValue, iBaseAtk,
                            stSkillEffect, stReviseUnit.GetAddNum());
                
                        i64AtkValue += iChgValue;
                
                        CT_BATTLE(("修正后伤害(%lld) ChgValue(%d) 次效果(%d)",
                            i64AtkValue,iChgValue,stReviseUnit.GetAddNum()));
                    }
                    break;

                default://不指定子类型 默认直接修改atk value
                    {
                        if (stReviseUnit.GetAddNum() <= 0)
                        {
                            CT_BATTLE(("角色(%u)默认修正伤害,叠加层数(%d)",
                                stBattleRole.GetRoleID(),
                                stReviseUnit.GetAddNum()));
                            break;
                        }
                
                        SkillPreEffectDataCalc(iChgValue, iBaseAtk,
                            stSkillEffect, stReviseUnit.GetAddNum());
                
                        i64AtkValue += iChgValue;
                
                        CT_BATTLE(("修正后伤害(%lld) ChgValue(%d) 叠加层数(%d)",
                            i64AtkValue,iChgValue,stReviseUnit.GetAddNum()));
                    }
                    break;
                }
            }
            break;

        case CSkillEffect::SKILL_STAT_BUFF_1: //BUFF类型1
        case CSkillEffect::SKILL_STAT_DEBUFF_1: //DEBUFF类型1
        case CSkillEffect::SKILL_STAT_BUFF_2: //BUFF类型2
        case CSkillEffect::SKILL_STAT_DEBUFF_2: //DEBUFF类型2
        case CSkillEffect::SKILL_STAT_BUFF_3: //BUFF类型3
        case CSkillEffect::SKILL_STAT_DEBUFF_3: //DEBUFF类型3
        case CSkillEffect::SKILL_STAT_BUFF_TREASURE: //秘宝产生的过程性效果
        case CSkillEffect::SKILL_STAT_BUFF_MOUNT: //坐骑产生的过程性效果
            {
                if (CSkillEffect::SKILL_SUB_STAT_REVISE_VAL !=
                        stSkillEffect.GetSubType())
                {
                    break;
                }

                if (stReviseUnit.GetAddNum() <= 0)
                {
                    CT_BATTLE(("角色(%u)默认修正伤害,叠加层数(%d)",
                        stBattleRole.GetRoleID(),stReviseUnit.GetAddNum()));
                    break;
                }

                SkillPreEffectDataCalc(iChgValue, iBaseAtk, stSkillEffect,
                    stReviseUnit.GetAddNum());
        
                i64AtkValue += iChgValue;
        
                CT_BATTLE(("修正后攻击伤害(%lld) ChgValue(%d) 叠加层数(%d)",
                    i64AtkValue,iChgValue,stReviseUnit.GetAddNum()));
            }
            break;

        default:
            break;
        }
    }

    return 0;
}

//计算Buff类加减血或者直接修改加减血
int CBattleRules::CalculateSkillEffectHP(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget, CSkillEffect& stSkillEffect,
        bool bIsFirst, int& iChangeHP)
{
    iChangeHP = 0;

    int iStatType = stSkillEffect.GetStatType();
    int iSubType = stSkillEffect.GetSubType();
    int iData = stSkillEffect.GetData();
    int iValueType = stSkillEffect.GetType();

    int iAttrValue = 0;
    int iTreatment = 0;
    int iImInjury = 0;
    int64 i64ValueTmp = 0;

    int iPreSkillSrcID = stBattleRole.GetRoleID();
    int iAttackAttr = stBattleRole.GetTypeAttr(EXT_ATTR_PHY_ATK, bIsFirst);
    int iMagicAttr = stBattleRole.GetTypeAttr(EXT_ATTR_MAG_ATK, bIsFirst);

    if (BATTLE_RULE_STAT_PRE_SKILL == GetRuleStat())
    {
        iPreSkillSrcID = GetPreSkillSrcID();
        if (BATTLE_INF->_pstRoles->IsValidRoleID(iPreSkillSrcID))
        {
            CBattleRole& stBattleSrcRole =
                BATTLE_INF->_pstRoles->GetRole(iPreSkillSrcID);

            iAttackAttr =
                stBattleSrcRole.GetTypeAttr(EXT_ATTR_PHY_ATK, bIsFirst);
            iMagicAttr =
                stBattleSrcRole.GetTypeAttr(EXT_ATTR_MAG_ATK, bIsFirst);
        }
    }

    //施法者综合攻击力 = (施法者物攻 + 施法者魔攻) / 2;
    iAttrValue = (iAttackAttr + iMagicAttr) / 2;

    CT_BATTLE(("施法者(%d)综合攻击力(%d) = (物攻(%d) + 魔攻(%d)) / 2",
               iPreSkillSrcID,iAttrValue,iAttackAttr,iMagicAttr));

    //加血需要加上痊愈系数 痊愈值是一个千分比而不是等级
    //加血量=施法者A综合攻击力 * 千分比系数 * (1 + B痊愈系数)
    if (iData > 0)
    {
        if (CSkillEffect::SKILL_SUB_STAT_HP == iSubType ||
            CSkillEffect::SKILL_STAT_BUFF_HOT == iStatType ||
            CSkillEffect::SKILL_STAT_BUFF_DOT == iStatType)
        {
            iTreatment = stBattleTarget.GetTypeAttr(EXT_ATTR_TREATMENT, bIsFirst);
            if (iTreatment < 0){iTreatment = 0;}
        }

        if (CSkillEffect::SKILL_STAT_VAL_RATE == iValueType)
        {
            i64ValueTmp = INT64_1 * iAttrValue * iData * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_NUM == iValueType)
        {
            //i64ValueTmp = INT64_1 * (iAttrValue + iData) * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp = INT64_1 * iData * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_MAX_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHPMax() * iData * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_BEFORE_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHPBeforeAtk() * iData * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_NOW_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHP() * iData * (iTreatment + BATTLE_RATE_SKILL_PERCENT);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else
        {
            CT_ERROR(("skill effect(%u) value type(%d) error!",
                      stSkillEffect.GetID(),iValueType));
            return -1;
        }

        iChangeHP = (int)i64ValueTmp;
    }
    //减血需要加上免伤系数 免伤是一个千分比而不是等级
    //减血量=施法者A综合攻击力 * 千分比系数 * (1 - B免伤系数)
    else if (iData < 0)
    {
        if (CSkillEffect::SKILL_SUB_STAT_HP == iSubType ||
            CSkillEffect::SKILL_STAT_BUFF_HOT == iStatType ||
            CSkillEffect::SKILL_STAT_BUFF_DOT == iStatType)
        {
            iImInjury = stBattleTarget.GetTypeAttr(EXT_ATTR_IMMUNE_INJURY, bIsFirst);
            if (iImInjury < 0)
            {
                iImInjury = 0;
            }
            else if (iImInjury > BATTLE_RATE_SKILL_PERCENT)
            {
                iImInjury = BATTLE_RATE_SKILL_PERCENT;
            }
        }

        if (CSkillEffect::SKILL_STAT_VAL_RATE == iValueType)
        {
            i64ValueTmp = INT64_1 * iAttrValue * iData * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_NUM == iValueType)
        {
            //i64ValueTmp = INT64_1 * ((-1) * iAttrValue + iData) * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp = INT64_1 * iData * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_MAX_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHPMax() * iData * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_BEFORE_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHPBeforeAtk() * iData * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else if (CSkillEffect::SKILL_STAT_VAL_RATE_OTHER_NOW_HP == iValueType)
        {
            i64ValueTmp = INT64_1 * stBattleRole.GetHP() * iData * (BATTLE_RATE_SKILL_PERCENT - iImInjury);
            i64ValueTmp /= (BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT);
        }
        else
        {
            CT_ERROR(("skill effect(%u) value type(%d) error!",
                      stSkillEffect.GetID(),iValueType));
            return -1;
        }

        iChangeHP = (int)(i64ValueTmp);
    }

    return 0;
}

int CBattleRules::CastSkillEffectOnRoleOneEffect(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget, CPlayerAttr& stBaseAttr,
        CPlayerAttr& stBattleAttr, CPlayerAttr& stTurnAttr,
        CSkillEffect& stSkillEffect, CStatusObj& stStatusObj, int iAuxAddNum,
        int& iBloodChg, bool bChangeHP, bool bIsFirst)
{
    int iRet = 0;
    int iChgValue = 0;
    int iRelation = GetRelation(stBattleRole, stBattleTarget);
    int64 i64ValueTmp = 0;

    CSkillEffect stSkillEffectTmp;
    CBattleReviseUnit stReviseUnit;

    unsigned char ucStatType = stSkillEffect.GetStatType(); 
    unsigned char ucSubType = stSkillEffect.GetSubType();

    switch (ucStatType)
    {
    //击飞和拖拽效果按照技能交互双方的概率计算 不放在这里(不保存在角色身上)
    case CSkillEffect::SKILL_STAT_SWIM:         //眩晕
    case CSkillEffect::SKILL_STAT_STICK:        //定身
    case CSkillEffect::SKILL_STAT_BUFF_HOT:     //加血
    case CSkillEffect::SKILL_STAT_BUFF_DOT:     //掉血
    case CSkillEffect::SKILL_STAT_BUFF_1:       //Buff类型1
    case CSkillEffect::SKILL_STAT_DEBUFF_1:     //DeBuff类型1
    case CSkillEffect::SKILL_STAT_BUFF_2:       //Buff类型2
    case CSkillEffect::SKILL_STAT_DEBUFF_2:     //DeBuff类型2
    case CSkillEffect::SKILL_STAT_BUFF_3:       //Buff类型3
    case CSkillEffect::SKILL_STAT_DEBUFF_3:     //DeBuff类型3
    case CSkillEffect::SKILL_STAT_BUFF_TREASURE: //秘宝产生的过程性效果
    case CSkillEffect::SKILL_STAT_BUFF_MOUNT: //坐骑产生的过程性效果
        {
            if (!stBattleTarget.InDefinitBuff(CSkillEffect::SKILL_STAT_IMMUNE_MAIN, ucStatType) &&
                !stBattleTarget.InDefinitSubBuff(CSkillEffect::SKILL_STAT_IMMUNE_SUB, ucStatType, ucSubType))
            {
                if (stSkillEffect.GetLastTurnCount() <= 0){break;}

                if (CSkillEffect::SKILL_STAT_BUFF_HOT == ucStatType ||
                    CSkillEffect::SKILL_STAT_BUFF_DOT == ucStatType ||
                    CSkillEffect::SKILL_SUB_STAT_HP == ucSubType)
                {
                    stSkillEffectTmp = stSkillEffect;

                    iRet = CalculateSkillEffectHP(stBattleRole,
                        stBattleTarget, stSkillEffect, bIsFirst,
                        iChgValue);
                    CT_RETURN(iRet);

                    stSkillEffectTmp.SetType(
                        CSkillEffect::SKILL_STAT_VAL_NUM);
                    stSkillEffectTmp.SetData(iChgValue);
                    
                    iRet = stBattleTarget.AddBuff(stSkillEffectTmp,
                        iRelation, stBattleRole.GetRoleID());
                    CT_RETURN(iRet);
                }
                else
                {
                    iRet = stBattleTarget.AddBuff(stSkillEffect, iRelation,
                        stBattleRole.GetRoleID());
                    CT_RETURN(iRet);
                }
            }
        }
        break;

    case CSkillEffect::SKILL_STAT_IMMUNE_MAIN:      //免疫主效果
    case CSkillEffect::SKILL_STAT_IMMUNE_SUB:       //免疫子效果
        if (stSkillEffect.GetLastTurnCount() > 0)
        {
            iRet = stBattleTarget.AddBuff(stSkillEffect, iRelation,
                stBattleRole.GetRoleID());
            CT_RETURN(iRet);
        }
        break;

    //预处理效果在回合效果在回合时候依据攻击者和受击者处理
    case CSkillEffect::SKILL_STAT_PRE_CASTER:       //预处理施法者
    case CSkillEffect::SKILL_STAT_PRE_TARGET:       //预处理受击者
        break;
    case CSkillEffect::SKILL_STAT_SHIELD: //护盾效果
        {
            if (!stBattleTarget.InDefinitBuff(CSkillEffect::SKILL_STAT_IMMUNE_MAIN, ucStatType))
            {
                if (stSkillEffect.GetLastTurnCount() <= 0){break;}

                stSkillEffectTmp = stSkillEffect;

                iRet = CalculateSkillEffectHP(stBattleRole,
                    stBattleTarget, stSkillEffect, bIsFirst,
                    iChgValue);
                CT_RETURN(iRet);

                stSkillEffectTmp.SetType(
                    CSkillEffect::SKILL_STAT_VAL_NUM);
                stSkillEffectTmp.SetData(iChgValue);
                
                iRet = stBattleTarget.AddBuff(stSkillEffectTmp,
                    iRelation, stBattleRole.GetRoleID());
                CT_RETURN(iRet);
            }
        }
        break;

    //以下是当回合结算的效果 不会加到角色buff列表 不受免疫效果影响
    case CSkillEffect::SKILL_STAT_REMOVE_MAIN:    //驱散主效果
        {
            iRet = stBattleTarget.DelBuffByStatType(ucSubType);
            CT_RETURN(iRet);
        }
        break;
    case CSkillEffect::SKILL_STAT_REMOVE_SUB:    //驱散子效果
        {
            iRet = stBattleTarget.DelBuffBySubType(ucSubType,
                    stSkillEffect.GetData());
            CT_RETURN(iRet);
        }
        break;
    case CSkillEffect::SKILL_STAT_MODIFY://直接修改角色属性如生命、勇气、怒气等
        {
            if (0 == stSkillEffect.GetData())
            {
                break;
            }

            if (iAuxAddNum > 0)
            {
                CT_BATTLE(("角色(%d)直接修正消耗型属性子类型(%d)额外修正倍率" \
                           "(%d)",stBattleTarget.GetRoleID(),ucSubType,
                           iAuxAddNum));
            }

            switch (ucSubType)
            {
            case CSkillEffect::SKILL_SUB_STAT_HP://直接修改生命
                {
                    iRet = CalculateSkillEffectHP(stBattleRole, stBattleTarget,
                        stSkillEffect, bIsFirst, iBloodChg);
                    CT_RETURN(iRet);

                    CT_BATTLE(("角色(%d)血量变化值(%d)",
                        stBattleTarget.GetRoleID(),iBloodChg));

                    if (iAuxAddNum > 0)
                    {
                        iBloodChg *= iAuxAddNum;

                        CT_BATTLE(("角色(%d)血量修正(%d)后变化值(%d)",
                            stBattleTarget.GetRoleID(),iAuxAddNum,iBloodChg));
                    }
                        
                    if (bChangeHP)
                    {
                        stBattleTarget.ModRoleHP(iBloodChg,
                            stBattleRole.GetRoleID());
                    }
                }
                break;
            case CSkillEffect::SKILL_SUB_STAT_COURAGE://直接修改勇气
                {
                    iChgValue = 0;
                    if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_RATE))
                    {
                        i64ValueTmp = INT64_1 * stBattleTarget.GetCourageMax() * stSkillEffect.GetData();
                        i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
                        iChgValue = (int)(i64ValueTmp);
                    }
                    else if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_NUM))
                    {
                        iChgValue = stSkillEffect.GetData();
                    }

                    if (iAuxAddNum > 0)
                    {
                        iChgValue = iChgValue * iAuxAddNum;
                    }

                    stBattleTarget.ModCourage(iChgValue);

                    if (stSkillEffect.GetData() < 0 && stBattleTarget.GetCourage() <= 0 &&
                        !stBattleTarget.IsHaveToTurnWait() && !stBattleTarget.IsRecvCourageAndAct())
                    {
                        stBattleTarget.SetFallBackRightNow();
                    }
                    
                    if (stSkillEffect.GetData() > 0 && stBattleTarget.IsFallBackRightNow() &&
                        stBattleTarget.GetCourage() > 0)
                    {
                        stBattleTarget.SetCourageNormal();
                    }
                }
                break;
            case CSkillEffect::SKILL_SUB_STAT_ANGER://直接修改怒气
                {
                    iChgValue = 0;
                    if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_RATE))
                    {
                        i64ValueTmp = INT64_1 * MAX_ROLE_ANGER_ADD * stSkillEffect.GetData();
                        i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
                        iChgValue = (int)(i64ValueTmp);
                    }
                    else if (stSkillEffect.IsDefType(CSkillEffect::SKILL_STAT_VAL_NUM))
                    {
                        iChgValue = stSkillEffect.GetData();
                    }

                    if (iAuxAddNum > 0)
                    {
                        iChgValue = iChgValue * iAuxAddNum;
                    }

                    stBattleTarget.ModAnger(iChgValue);
                }
                break;
            default:
                CT_WARNING(("Unknow Buff(%d) Stattype(%d) Subtype(%d)",
                            stSkillEffect.GetID(),ucStatType,ucSubType));
                break;
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_DEAD_KILL://斩杀效果直接清空角色生命属性
        {
            iBloodChg = 0 - stBattleTarget.GetHP();

            CT_BATTLE(("角色(%d)被斩杀血量变化值(%d)", stBattleTarget.GetRoleID(), iBloodChg));
                
            if (bChangeHP)
            {
                stBattleTarget.ModRoleHP(iBloodChg,
                    stBattleRole.GetRoleID());
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_HITBACK:    //击飞
    case CSkillEffect::SKILL_STAT_PULL:       //拖拽
        break;
    case CSkillEffect::SKILL_STAT_REVISE_VAL: //修正战斗结算数值
        {
            stReviseUnit.Clear();
            stReviseUnit.SetEffectID(stSkillEffect.GetID());
            switch (ucSubType)
            {
            case CSkillEffect::SKILL_SUB_STAT_ANGER://怒气
                {
                    int iAnger = stBattleRole.GetAnger();
                    if (iAnger < stBattleRole.GetUseAnger())
                    {
                        iAnger = stBattleRole.GetUseAnger();
                    }
            
                    iAnger /= TREASURE_ANGER_COST_UNIT;
            
                    CT_BATTLE(("角色(%d)当前怒气(%d)使用怒气(%d)怒气消耗单元" \
                               "(%d)怒气倍率(%d)",stBattleRole.GetRoleID(),
                               stBattleRole.GetAnger(),
                               stBattleRole.GetUseAnger(),
                               TREASURE_ANGER_COST_UNIT,iAnger));
            
                    if (iAnger <= 0)
                    {
                        break;
                    }
            
                    stStatusObj._iAuxData = iAnger + iAuxAddNum;
                    stReviseUnit.SetAddNum(iAnger + iAuxAddNum);
                    _stBattleReviseAtk.AddReviseUnit(stReviseUnit);
                }
                break;
            case CSkillEffect::SKILL_SUB_STAT_DISTANCE://站位距离
                {
                    int iDistance = stBattleRole.GetGridIndex() -
                            stBattleTarget.GetGridIndex();
                    if (iDistance < 0)
                    {
                        iDistance = 0 - iDistance;
                    }
                    else if (0 == iDistance)
                    {
                        CT_WARNING(("Role(%d) Target(%d) Distance(%d)",
                                    stBattleRole.GetRoleID(),
                                    stBattleTarget.GetRoleID(),iDistance));
                        break;
                    }
            
                    CT_BATTLE(("角色(%d)站位(%d)目标(%d)站位(%d)站位距离(%d)",
                               stBattleRole.GetRoleID(),
                               stBattleRole.GetGridIndex(),
                               stBattleTarget.GetRoleID(),
                               stBattleTarget.GetGridIndex(),iDistance));
            
                    stReviseUnit.SetAddNum(iDistance + iAuxAddNum);
                    _stBattleReviseAtk.AddReviseUnit(stReviseUnit);
                }
                break;
            case CSkillEffect::SKILL_SUB_STAT_REVISE://下一次行动开始且整个战斗都生效的修正伤害
                {
                    ++stStatusObj._iAddNum;
                    stStatusObj._iAddNum += iAuxAddNum;
                    stStatusObj._iAuxData = stStatusObj._iAddNum;
                }
                break;
            case CSkillEffect::SKILL_SUB_STAT_REVISE_OBJECT://只是当回合生效的伤害修正 aux_data特定目标
                {
                    if (stSkillEffect.GetAuxData() > 0)
                    {
                        stReviseUnit.SetTargetID(stBattleTarget.GetRoleID());
                    }

                    stReviseUnit.SetAddNum(1 + iAuxAddNum);
                    _stBattleReviseAtk.AddReviseUnit(stReviseUnit);
                }
                break;
            default:
                {
                    stReviseUnit.SetAddNum(1 + iAuxAddNum);
                    _stBattleReviseAtk.AddReviseUnit(stReviseUnit);
                }
                break;
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_AMEND_ATTR: //修正个体二级属性
        {
            iChgValue = 0;

            if (ucSubType < EXT_ATTR_MIM || ucSubType >= EXT_ATTR_MAX)
            {
                CT_WARNING(("Unknow Buff(%u) Stattype(%d) Subtype(%d)",
                            stSkillEffect.GetID(),ucStatType,ucSubType));
                break;
            }

            if (stStatusObj._iAddNum > 0)
            {
                CT_BATTLE(("个体(%d)修正前:二级属性类型(%d)当前数值(%d)",
                           stBattleTarget.GetRoleID(),ucSubType,
                           stBattleAttr.GetAttr(ucSubType)));

                SkillPreEffectDataCalc(iChgValue, stBaseAttr.GetAttr(ucSubType),
                    stSkillEffect, stStatusObj._iAddNum + iAuxAddNum);

                iChgValue = stBattleAttr.GetAttr(ucSubType) + iChgValue;

                stBattleAttr.SetAttr(ucSubType, iChgValue);

                stStatusObj._iAuxData += (stStatusObj._iAddNum+iAuxAddNum);

                CT_BATTLE(("个体(%d)修正后:二级属性类型(%d)当前数值(%d)" \
                           "修正倍率(%d)",
                           stBattleTarget.GetRoleID(),ucSubType,
                           stBattleAttr.GetAttr(ucSubType),
                           stStatusObj._iAddNum + iAuxAddNum));
            }
            else
            {
                CT_WARNING(("skill effect(%u) stat type(%d) sub type(%d)" \
                            " add num(%d)",stSkillEffect.GetID(),ucStatType,
                            ucSubType,stStatusObj._iAddNum+iAuxAddNum));
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_AMEND_ATTR_TURN: //修正个体二级属性只是当前回合有效
        {
            iChgValue = 0;

            if (ucSubType < EXT_ATTR_MIM || ucSubType >= EXT_ATTR_MAX)
            {
                CT_WARNING(("Unknow Buff(%u) Stattype(%d) Subtype(%d)",
                            stSkillEffect.GetID(),ucStatType,ucSubType));
                break;
            }

            if (stStatusObj._iAddNum > 0)
            {
                CT_BATTLE(("个体(%d)修正前:二级属性类型(%d)当前数值(%d)",
                           stBattleTarget.GetRoleID(),ucSubType,
                           stTurnAttr.GetAttr(ucSubType)));

                SkillPreEffectDataCalc(iChgValue, stBaseAttr.GetAttr(ucSubType),
                    stSkillEffect, stStatusObj._iAddNum + iAuxAddNum);

                iChgValue = stTurnAttr.GetAttr(ucSubType) + iChgValue;

                stTurnAttr.SetAttr(ucSubType, iChgValue);

                stStatusObj._iAuxData += (stStatusObj._iAddNum+iAuxAddNum);

                CT_BATTLE(("个体(%d)修正后:二级属性类型(%d)当前数值(%d)" \
                           "修正倍率(%d)",
                           stBattleTarget.GetRoleID(),ucSubType,
                           stTurnAttr.GetAttr(ucSubType),
                           stStatusObj._iAddNum + iAuxAddNum));
            }
            else
            {
                CT_WARNING(("skill effect(%u) stat type(%d) sub type(%d)" \
                            " add num(%d)",stSkillEffect.GetID(),ucStatType,
                            ucSubType,stStatusObj._iAddNum+iAuxAddNum));
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_RANDOM: //产生一个随机数
        {
            //暂时不检查数值类型 data为正就以此随机 否则默认千分比随机
            int iData = stSkillEffect.GetData();
            if (iData > 0)
            {
                stStatusObj._iAuxData = CBattleRandom::GetRand(iData);
            }
            else
            {
                stStatusObj._iAuxData =
                    CBattleRandom::GetRand(BATTLE_RATE_SKILL_PERCENT);
            }

            SetSkillRandom(stStatusObj._iAuxData);

            CT_BATTLE(("角色(%d)随机特效(%u)随机结果(%d)",
                       stBattleRole.GetRoleID(),stSkillEffect.GetID(),
                       stStatusObj._iAuxData));
        }
        break;
    case CSkillEffect::SKILL_STAT_GROUP_CMD_START: //输出组合命令开启
        {
            BATTLE_INF->_pstVideo->GroupCmdStart();
        }
        break;
    case CSkillEffect::SKILL_STAT_GROUP_CMD_STOP: //输出组合命令关闭
        {
            BATTLE_INF->_pstVideo->GroupCmdStop();
        }
        break;
    case CSkillEffect::SKILL_STAT_FRONT_EFF_VIDEO: //输出Buff增加方便前端展示后端不处理
        {
            if (GetSkillRandom() >= 0)
            {
                stBattleTarget.RoleAddBuffVideo(stSkillEffect.GetID(),
                    iRelation, stBattleRole.GetRoleID(),
                    stSkillEffect.GetLastTurnCount(), GetSkillRandom() + 1);
            }
            else
            {
                stBattleTarget.RoleAddBuffVideo(stSkillEffect.GetID(),
                    iRelation, stBattleRole.GetRoleID(),
                    stSkillEffect.GetLastTurnCount(), 1);
            }
        }
        break;
    case CSkillEffect::SKILL_STAT_FRONT_DIE_VIDEO: //输出主角死亡方便前端展示后端不处理
        {
            BATTLE_INF->_pstVideo->RoleDead(stBattleRole.GetRoleID());
            SetNowDeader(stBattleRole.GetRoleID());
        }
        break;
    case CSkillEffect::SKILL_STAT_FRONT_WAIT_VIDEO://输出主角等待方便前端展示后端不处理
        {
            BATTLE_INF->_pstVideo->RoleWaitTime(stBattleRole.GetRoleID(),
                stSkillEffect.GetData());
        }
        break;
    default:
        {
            CT_WARNING(("Unknow Buff(%d) Stattype(%d)",
                        stSkillEffect.GetID(),ucStatType));
        }
        break;
    }

    return 0;
}

int CBattleRules::CastSkillEffectOnRole(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget, CSkillAffect& stSkillAffect,
        CStatusObj& stStatusObj, int iAuxAddNum, int& iBloodChg, bool bChangeHP,
        bool bIsFirst)
{
    iBloodChg = 0;//技能直接修改血量 前端需要播放动作 bChangeHP决定是否传出

    if (stSkillAffect.GetSkillEffectSize() <= 0)
    {
        return 0;
    }

    int iRet = 0;
    bool bHasAddRandom = false;

    CPlayerAttr& stSelfBaseAttr = stBattleRole.GetBaseAttr();
    CPlayerAttr& stSelfBattleAttr = stBattleRole.GetBattleAttr();
    CPlayerAttr& stSelfTurnAttr = (bIsFirst ? stBattleRole.GetTurnMainAttr(): stBattleRole.GetTurnMinorAttr());

    CPlayerAttr& stBaseAttr = stBattleTarget.GetBaseAttr();
    CPlayerAttr& stBattleAttr = stBattleTarget.GetBattleAttr();
    CPlayerAttr& stTurnAttr = (bIsFirst ? stBattleTarget.GetTurnMainAttr(): stBattleTarget.GetTurnMinorAttr());

    if (!bChangeHP)
    {
        CT_BATTLE(("角色(%d)主导的效果结算开始",stBattleRole.GetRoleID()));
        stBattleTarget.DumpBattleBuffList();
    }

    int iRandom = 0;
    int iAddRatio = 0;
    bool bTriggerDeadSkill = false;
    int64 i64RatioTmp = 0;

    for (int i = 0; i < stSkillAffect.GetSkillEffectSize(); ++i)
    {
        CSkillEffect& stSkillEffect = stSkillAffect.GetSkillEffect(i);

        bTriggerDeadSkill = false;

        if (CSkillEffect::SKILL_STAT_DEAD_KILL == stSkillEffect.GetStatType() && stBattleTarget.GetHP() > 0)
        {
            i64RatioTmp = INT64_1 * stBattleRole.GetHPMax() * BATTLE_RATE_SKILL_PERCENT;
            if (i64RatioTmp >= stBattleTarget.GetHP() * stSkillEffect.GetData())
            {
                bTriggerDeadSkill = true;
            }
        }

        //斩杀效果的概率需要额外处理
        if (bTriggerDeadSkill)
        {
            i64RatioTmp = INT64_1 * stBattleRole.GetHPMax() * BATTLE_RATE_SKILL_PERCENT;
            i64RatioTmp -= stBattleTarget.GetHP() * stSkillEffect.GetData();
            i64RatioTmp *= stSkillEffect.GetAuxData();
            i64RatioTmp /= (stBattleTarget.GetHP() * 10);
            iAddRatio = (int)i64RatioTmp;
            if (iAddRatio < 0){iAddRatio = 0;}
            
            iRandom = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
            if (iRandom >= stSkillEffect.GetTriggerRate() + iAddRatio)
            {
                CT_BATTLE(("效果(%d)概率(%d)不小于触发值(%d)",stSkillEffect.GetID(), iRandom,
                    stSkillEffect.GetTriggerRate()+iAddRatio));
                return 0;//后续的效果也不执行
            }

            _bTriggerDeadKill = true;
        }
        else
        {
            iRandom = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);
            if (iRandom >= stSkillEffect.GetTriggerRate())
            {
                CT_BATTLE(("效果(%d)概率(%d)不小于触发值(%d)",stSkillEffect.GetID(),
                           iRandom,stSkillEffect.GetTriggerRate()));
                continue;
            }
        }

        if (!bHasAddRandom && GetSkillRandom() >= 0)
        {
            iAuxAddNum += (GetSkillRandom() + 1);
            bHasAddRandom = true;
        }

        if (stSkillEffect.GetAuxData() == 0 || bTriggerDeadSkill)
        {
            iRet = CastSkillEffectOnRoleOneEffect(stBattleRole, stBattleTarget,
                stBaseAttr, stBattleAttr, stTurnAttr, stSkillEffect,
                stStatusObj, iAuxAddNum, iBloodChg, bChangeHP, bIsFirst);
            CT_RETURN(iRet);
        }
        else
        {
            iRet = CastSkillEffectOnRoleOneEffect(stBattleRole, stBattleRole,
                stSelfBaseAttr, stSelfBattleAttr, stSelfTurnAttr, stSkillEffect,
                stStatusObj, iAuxAddNum, iBloodChg, bChangeHP, bIsFirst);
            CT_RETURN(iRet);
        }
    }

    if (!bChangeHP)
    {
        CT_BATTLE(("角色(%d)主导的效果结算结束",stBattleRole.GetRoleID()));
        stBattleTarget.DumpBattleBuffList();
    }

    return 0;
}

int CBattleRules::StatusSkillEffect(CBattleRole& stBattleRole,
        CBattleRole& stBattleTarget, CSkillAffect& stSkillAffect,
        CStatusObj& stStatusObj, int iAuxAddNum)
{
    int iBloodChg = 0;
    ClearSkillRandom();
    bool bIsFirst = (BATTLE_RULE_STAT_MAIN_DO == GetRuleStat());
    return CastSkillEffectOnRole(stBattleRole, stBattleTarget, stSkillAffect,
            stStatusObj, iAuxAddNum, iBloodChg, true, bIsFirst);
}

void CBattleRules::VideoAllSkillRoleDead()
{
    for (int i = 0; i < GetSkillDeadSize(); ++i)
    {
        BATTLE_INF->_pstVideo->RoleDead(GetSkillDead(i));
    }
}

int CBattleRules::SkillEffect2(CBattleRole& stRole, CSkill& stSkill,
        CBattleSkillCastEffect& stSkillCastEffect, bool bIsFirst)
{
    int iRet = 0;
    int iSkillTargetStat = 0;

    CStatusObj stStatusObjTmp;
    stStatusObjTmp._iAddNum = 1;

    bool bIsMainToEnemy = bIsFirst && stSkill.IsMainToEnemy();
    bool bIsMinorToEnemy = !bIsFirst && stSkill.IsMinorToEnemy();

    bool bIsToEnemy = bIsMainToEnemy || bIsMinorToEnemy;

    //状态处理 STATUS_TRIGGER_CAST_MAGIC_SKILL //发动幻化技能时触发
    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole, CStatusMgr::STATUS_TRIGGER_CAST_MAGIC_SKILL, 0);

    CT_BATTLE(("技能(%u)伤害目标总数(%d)",stSkill.GetID(), stSkillCastEffect._astTargets.Size()));

    int iRoleID = 0;
    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        iRoleID = stSkillCastEffect._astTargets[i].GetID();

        CT_BATTLE(("角色(%d)是否被命中(%d)", iRoleID, stSkillCastEffect._astTargets[i].IsHitted()));

        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }

        if (!stSkillCastEffect._astTargets[i].IsHitted())
        {
            if (bIsToEnemy)
            {
                SetNowTarget(stSkillCastEffect._astTargets[i].GetID());

                if (BATTLE_RULE_STAT_PRE_SKILL != GetRuleStat())
                {
                    BATTLE_INF->_pstVideo->LostBloodBySkill(stSkillCastEffect._astTargets[i].GetID(), 0, 0, -1, -1);
                }

                //状态处理 STATUS_TRIGGER_ATK_DODGE //攻击被闪避时触发
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole, CStatusMgr::STATUS_TRIGGER_ATK_DODGE, 0);

                CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

                //状态处理 STATUS_TRIGGER_DODGE_ATK //闪避攻击时触发
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                    CStatusMgr::STATUS_TRIGGER_DODGE_ATK, 0);
            }

            continue;
        }

        _bTriggerDeadKill = false;
        iSkillTargetStat = BATTLE_VIDEO_SKILL_HIT;

        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

        CPlayerAttr& stTargetPreAttr = (bIsFirst ? stTargetRole._stTurnMainAttr : stTargetRole._stTurnMinorAttr);

        bool bLeftSide = stTargetRole.IsLeft();
        CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

        int iDstGrid = -1;
        int iHitBackDist = stSkillCastEffect._astTargets[i].GetHitBackDistance();
        int iPullDist = stSkillCastEffect._astTargets[i].GetPullDistance();
        int iTargetOriRelatGrid = stTargetRole.GetRelatGridIndex(bLeftSide);
        if (iHitBackDist > 0)//击飞
        {
            iDstGrid = CT_MAX(0, iTargetOriRelatGrid - iHitBackDist);

            if (iDstGrid != iTargetOriRelatGrid)
            {
                iRet = RoleMoveTo(stTargetRole, iDstGrid, false);
                CT_RETURN(iRet);

                iHitBackDist = iTargetOriRelatGrid - stTargetRole.GetRelatGridIndex(bLeftSide);

                stSkillCastEffect._astTargets[i].SetHitBackDistance(iHitBackDist);

                CT_BATTLE(("角色(%d)被击飞到格子(%d)击飞距离(%d)", stTargetRole.GetRoleID(),
                    stTargetRole.GetRelatGridIndex(stRole.IsLeft()), iHitBackDist));
            }
            else
            {
                stSkillCastEffect._astTargets[i].SetHitBackDistance(0);
            }

            stSkillCastEffect._astTargets[i].SetPullDistance(0);
        } 
        else if (iPullDist > 0)//拖拽
        {
            iDstGrid = CT_MIN(stMapSide.GetRightFrontTo() - 1, iTargetOriRelatGrid + iPullDist);
            iDstGrid = iDstGrid < 0 ? 0 : iDstGrid;

            if (iDstGrid != iTargetOriRelatGrid)
            {
                iRet = RoleMoveTo(stTargetRole, iDstGrid, false);
                CT_RETURN(iRet);

                iPullDist = stTargetRole.GetRelatGridIndex(bLeftSide) - iTargetOriRelatGrid;

                stSkillCastEffect._astTargets[i].SetPullDistance(iPullDist);
                CT_BATTLE(("角色(%d)被拖拽到格子(%d)拖拽距离(%d)", stTargetRole.GetRoleID(),
                    stTargetRole.GetRelatGridIndex(stRole.IsLeft()),iPullDist));
            }
            else
            {
                stSkillCastEffect._astTargets[i].SetPullDistance(0);
            }

            stSkillCastEffect._astTargets[i].SetHitBackDistance(0);
        }

        //目标击飞或者拖拽后以下伤害计算有可能导致目标死亡 死亡后取目标坐标会返回-1 导致不准
        int iTargetGridPos = stTargetRole.GetGridIndex();
        int iTargetHPBefore = stTargetRole.GetHP();

        //技能附带效果处理
        int iBloodChg = 0;

        if (BATTLE_RULE_STAT_PRE_SKILL != GetRuleStat())
        {
            iRet = CastSkillEffectOnRole(stRole, stTargetRole, stSkillCastEffect._stSkillAffect, stStatusObjTmp, 0,
                iBloodChg, false, bIsFirst);
            CT_RETURN(iRet);
        }
        else
        {
            iRet = CastSkillEffectOnRole(stRole, stTargetRole, stSkillCastEffect._stSkillAffect, stStatusObjTmp, 0,
                iBloodChg, true, bIsFirst);
            CT_RETURN(iRet);
        }
 
        if (_bTriggerDeadKill)
        {
            iSkillTargetStat |= BATTLE_VIDEO_DEAD_KILL;
        }

        CT_BATTLE(("角色(%d)因技能作用血量直接变化量(%d)",stTargetRole.GetRoleID(),iBloodChg));

        if (!bIsToEnemy)
        {
            int iHitBackGird = -1;
            int iPullGird = -1;

            if (stSkillCastEffect._astTargets[i].GetHitBackDistance() > 0)
            {
                iHitBackGird = iTargetGridPos;
            }
            else if (stSkillCastEffect._astTargets[i].GetPullDistance() > 0)
            {
                iPullGird = iTargetGridPos;
            }

            if (0 != iBloodChg && BATTLE_RULE_STAT_PRE_SKILL != GetRuleStat())
            {
                stTargetRole.ChgBlood(iBloodChg);

                BATTLE_INF->_pstVideo->LostBloodBySkill(stTargetRole.GetRoleID(), iSkillTargetStat, iBloodChg,
                    iHitBackGird, iPullGird);

                stTargetRole.RoleAttrChg(iTargetHPBefore);
            }

            if (stTargetRole.HasDead())
            {
                BATTLE_INF->_pstRules->SetNowKiller(stRole.GetRoleID());

                //状态处理 STATUS_TRIGGER_SELF_DIE //自己死亡时触发
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                    CStatusMgr::STATUS_TRIGGER_SELF_DIE, 0);

                //状态处理 STATUS_TRIGGER_SELF_DIE_ALL_DIE
                //自己死亡时触发 且是本方最后一个死亡 +
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                    CStatusMgr::STATUS_TRIGGER_SELF_DIE_ALL_DIE, 0);

                if (GetNowDeader() != stTargetRole.GetRoleID())
                {
                    CT_BATTLE(("角色(%d)因受击血量为0而死亡", stTargetRole.GetRoleID()));
                    //BATTLE_INF->_pstVideo->RoleDead(stTargetRole.GetRoleID());
                    AddSkillDead(stTargetRole.GetRoleID());
                }

                //状态处理 STATUS_TRIGGER_ATK_OBJ_DIE //攻击目标死亡时触发
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                    CStatusMgr::STATUS_TRIGGER_ATK_OBJ_DIE, 0);

                CMapSide& stMapSideTemp = BATTLE_INF->_pstMap->GetMapSide(stTargetRole.IsLeft());
                MAP_GRID_MULTI stMapGridMulti;
                stMapSideTemp.GetDistanceRoles(0, stMapSideTemp.GetLeftFrontTo(), stMapGridMulti);
                for (int i = 0; i < stMapGridMulti.Size(); ++i)
                {
                    if (!BATTLE_INF->_pstRoles->IsValidRoleID(
                            stMapGridMulti[i].GetRoleID()))
                    {
                        continue;
                    }
                    CBattleRole& stTeamRole = BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[i].GetRoleID());
                
                    //状态处理 STATUS_TRIGGER_TEAMMATE_DIE //队友死亡时触发
                    CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTeamRole,
                        CStatusMgr::STATUS_TRIGGER_TEAMMATE_DIE, 0);
                }
            }

            CT_BATTLE(("非敌技能功能不对目标进行伤害计算"));

            continue;
        }

        SetNowTarget(stSkillCastEffect._astTargets[i].GetID());

        CPlayerAttr& stRolePreAttr = (bIsFirst ? stRole._stTurnMainAttr : stRole._stTurnMinorAttr);

        //以下是技能伤害计算
        _i64AtkValue = 0;
        int64 i64AtkTemp = 0;

        //技能系数
        int iSkillRatio = stSkillCastEffect._stSkillAffect.GetAtkValue();
        if (iSkillRatio < 0){iSkillRatio = 0;}

        int iAPhyAtk = stRole.GetTypeAttr(EXT_ATTR_PHY_ATK, bIsFirst);//物攻
        if (iAPhyAtk < 0){iAPhyAtk = 0;}
        int iAMagAtk = stRole.GetTypeAttr(EXT_ATTR_MAG_ATK, bIsFirst);//法攻
        if (iAMagAtk < 0){iAMagAtk = 0;}

        CT_BATTLE(("角色(%d)物攻(%d)法攻(%d)技能(%u)功能(%u)技能系数(%d)",
            stRole.GetRoleID(),iAPhyAtk,iAMagAtk,stSkill.GetID(),
            stSkillCastEffect._stSkillAffect.GetID(),iSkillRatio));

        //普通技能
        if (stSkill.IsNormalSkill() && BATTLE_RULE_STAT_HIT_BACK != GetRuleStat())
        {
            if (stSkillCastEffect._stSkillAffect.IsPhy())
            {
                int iBPhyDef = stTargetRole.GetTypeAttr(EXT_ATTR_PHY_DEF, bIsFirst);
                if (iBPhyDef < 0){iBPhyDef = 0;}
                _i64AtkValue = iAPhyAtk - iBPhyDef;
                if (_i64AtkValue < 0){_i64AtkValue = 0;}
                CT_BATTLE(("普通物理技能(%u)功能(%u):一次伤害(%lld)=A物攻(%d)-B物防(%d)",
                            stSkill.GetID(),stSkillCastEffect._stSkillAffect.GetID(),
                            _i64AtkValue,iAPhyAtk,iBPhyDef));
            }
            else
            {
                int iBMagDef = stTargetRole.GetTypeAttr(EXT_ATTR_MAG_DEF, bIsFirst);
                if (iBMagDef < 0){iBMagDef = 0;}
                _i64AtkValue = iAMagAtk - iBMagDef;
                if (_i64AtkValue < 0){_i64AtkValue = 0;}
                CT_BATTLE(("普通魔法技能(%u)功能(%u):一次伤害(%lld)=A魔攻(%d)-B魔防(%d)",
                            stSkill.GetID(),stSkillCastEffect._stSkillAffect.GetID(),
                            _i64AtkValue,iAMagAtk,iBMagDef));
            }
        }
        else if (stSkill.IsNormalSkill() && BATTLE_RULE_STAT_HIT_BACK == GetRuleStat())
        {
            int iAAtkVal = 0;
            int iBDefVal = 0;

            //反伤是一个千分比而不是等级
            int iReactVal = stRole.GetTypeAttr(EXT_ATTR_REACT_INJURY, bIsFirst);
            if (iReactVal < 0){iReactVal = 0;}

            if (stSkillCastEffect._stSkillAffect.IsPhy())
            {
                iAAtkVal = iAPhyAtk;
                iBDefVal = stTargetRole.GetTypeAttr(EXT_ATTR_PHY_DEF, bIsFirst);
                if (iBDefVal < 0){iBDefVal = 0;}
            }
            else
            {
                iAAtkVal = iAMagAtk;
                iBDefVal = stTargetRole.GetTypeAttr(EXT_ATTR_MAG_DEF, bIsFirst);
                if (iBDefVal < 0){iBDefVal = 0;}
            }

            _i64AtkValue = INT64_1 * (iAAtkVal - iBDefVal) * (BATTLE_RATE_SKILL_PERCENT + iReactVal);
            _i64AtkValue /= (2 * BATTLE_RATE_SKILL_PERCENT);
            if (_i64AtkValue < 0){_i64AtkValue = 0;}

            CT_BATTLE(("反击技能(%u)功能(%u):一次伤害(%lld)",stSkill.GetID(),
                stSkillCastEffect._stSkillAffect.GetID(),_i64AtkValue));
        }
        //学院技能及幻化技能
        else if (stSkill.IsAcademicSkill() || stSkill.IsMagicSkill())
        {
            CT_BATTLE(("学院技能或幻化技能(%d)功能(%u)",stSkill.GetID(),
                stSkillCastEffect._stSkillAffect.GetID()));

            int iAAtkValue = 0;
            int iBMainDef = 0;
            int iBMinorDef = 0;

            //穿透是一个千分比而不是等级
            int iPenetrate = stRole.GetTypeAttr(EXT_ATTR_PENETRATE, bIsFirst);
            if (iPenetrate < 0)
            {
                iPenetrate = 0;
            }
            else if (iPenetrate > BATTLE_RATE_SKILL_PERCENT)
            {
                iPenetrate = BATTLE_RATE_SKILL_PERCENT;
            }

            if (stSkillCastEffect._stSkillAffect.IsPhy())
            {
                iAAtkValue = iAPhyAtk;
                iBMainDef = stTargetRole.GetTypeAttr(EXT_ATTR_PHY_DEF, bIsFirst);
                iBMinorDef = stTargetRole.GetTypeAttr(EXT_ATTR_MAG_DEF, bIsFirst) / 4;
                if (iBMainDef < 0){iBMainDef = 0;}
                if (iBMinorDef < 0){iBMinorDef = 0;}

            }
            else
            {
                iAAtkValue = iAMagAtk;
                iBMainDef = stTargetRole.GetTypeAttr(EXT_ATTR_MAG_DEF, bIsFirst);
                iBMinorDef = stTargetRole.GetTypeAttr(EXT_ATTR_PHY_DEF, bIsFirst) / 4;
                if (iBMainDef < 0){iBMainDef = 0;}
                if (iBMinorDef < 0){iBMinorDef = 0;}
            }

            int iRoleAnger = stRole.GetUseAnger();
            int iSkillAnger = stSkill.GetUseAnger();

            if (iRoleAnger > 0 && iSkillAnger > 0 && iRoleAnger >= iSkillAnger)
            {
                //伤害=主攻*(技能系数+1000)-(主防+次防)*(1000-穿透)
                //伤害*=((1000*技能怒气)+(消耗怒气-技能怒气)*250)
                //伤害/=(1000*1000*技能怒气)
                _i64AtkValue =
                    (INT64_1 * iAAtkValue * (BATTLE_RATE_SKILL_PERCENT + iSkillRatio)) -
                        INT64_1 * (iBMainDef + iBMinorDef) * (BATTLE_RATE_SKILL_PERCENT - iPenetrate);

                _i64AtkValue *= ((INT64_1 * BATTLE_RATE_SKILL_PERCENT * iSkillAnger) + INT64_1 * (iRoleAnger - iSkillAnger) * 250);

                _i64AtkValue /= (INT64_1 * BATTLE_RATE_SKILL_PERCENT * BATTLE_RATE_SKILL_PERCENT * iSkillAnger);

                CT_BATTLE(("怒气修正后伤害(%lld):技能(%u)技能怒气(%d)角色怒气(%d)角色穿透(%d)",
                    _i64AtkValue,stSkill.GetID(),iSkillAnger,iRoleAnger,iPenetrate));
            }
            else
            {
                //伤害=主攻*(技能系数+1000)-(主防+次防)*(1000-穿透)
                //伤害/=(1000)
                _i64AtkValue =
                    INT64_1 * (INT64_1 * iAAtkValue * (BATTLE_RATE_SKILL_PERCENT + iSkillRatio)) -
                        INT64_1 * (iBMainDef + iBMinorDef) * (BATTLE_RATE_SKILL_PERCENT - iPenetrate);

                _i64AtkValue /= BATTLE_RATE_SKILL_PERCENT;

                CT_BATTLE(("没有怒气的伤害(%lld):技能(%u)技能怒气(%d)角色怒气(%d)角色穿透(%d)",
                    _i64AtkValue,stSkill.GetID(),iSkillAnger,iRoleAnger,iPenetrate));
            }
        }
        else
        {
            CT_ERROR(("Unknown Skill(%u) Type(%d)",stSkill.GetID(),stSkill.GetType()));
            return 0;
        }

        //伤害下限
        if (stSkillCastEffect._stSkillAffect.IsPhy())
        {
            i64AtkTemp = iAPhyAtk / BATTLE_RATE_ATK_VAL_MIN;
        }
        else
        {
            i64AtkTemp = iAMagAtk / BATTLE_RATE_ATK_VAL_MIN;
        }

        if (_i64AtkValue < i64AtkTemp)
        {
            _i64AtkValue = i64AtkTemp;
            CT_BATTLE(("伤害下限修正后伤害(%lld)",_i64AtkValue));
        }

        //暴击
        int iADouble = stRole.GetTypeAttr(EXT_ATTR_DOUBLE, bIsFirst);
        if (iADouble < 0){iADouble = 0;}
        CT_BATTLE(("A暴击等级(%d) = A初始暴击等级(%d) + A预处理及Buff修正暴击等级(%d)",
                    iADouble,stRole.GetTypeAttr(EXT_ATTR_DOUBLE),
                    stRolePreAttr.GetAttr(EXT_ATTR_DOUBLE)));

        int iBAntiDouble = stTargetRole.GetTypeAttr(EXT_ATTR_ANTI_DOUBLE, bIsFirst);
        if (iBAntiDouble < 0){iBAntiDouble = 0;}
        CT_BATTLE(("B抗暴等级(%d) = B初始抗暴等级(%d) + B预处理及Buff修正抗暴等级(%d)",
                    iBAntiDouble,stTargetRole.GetTypeAttr(EXT_ATTR_ANTI_DOUBLE),
                    stTargetPreAttr.GetAttr(EXT_ATTR_ANTI_DOUBLE)));

#define DOUBLE_ANTI_MACRO_1 0.45
#define DOUBLE_ANTI_MACRO_2 50.0
#define DOUBLE_ANTI_MACRO_3 3.0
#define DOUBLE_ANTI_MACRO_4 4
#define DOUBLE_ANTI_MACRO_5 300

        double dDoubleAnti = 0.0;
        if (iADouble >= iBAntiDouble)
        {
            dDoubleAnti = (iADouble - iBAntiDouble) * 1.0;
            dDoubleAnti = (pow(dDoubleAnti, (double)DOUBLE_ANTI_MACRO_1) * DOUBLE_ANTI_MACRO_2) / (double)DOUBLE_ANTI_MACRO_3;

            CT_BATTLE(("修正后暴击抗暴(%0.2lf) = [(A总暴击等级(%d)-B总抗暴等级(%d))^(%f)]*(%f)/(%f)",
                        dDoubleAnti,iADouble,iBAntiDouble,DOUBLE_ANTI_MACRO_1,DOUBLE_ANTI_MACRO_2,DOUBLE_ANTI_MACRO_3));
        }
        else
        {
            dDoubleAnti = (iBAntiDouble - iADouble) * 1.0;
            dDoubleAnti =
                (-1) * (pow(dDoubleAnti, (double)DOUBLE_ANTI_MACRO_1) * DOUBLE_ANTI_MACRO_2) / (double)DOUBLE_ANTI_MACRO_3;

            CT_BATTLE(("修正后暴击抗暴(%0.2lf) = (-1) * [(B总抗暴等级(%d)-A总暴击等级(%d))^(%f)]*(%f)/(%f)",
                        dDoubleAnti,iBAntiDouble,iADouble,DOUBLE_ANTI_MACRO_1,DOUBLE_ANTI_MACRO_2,DOUBLE_ANTI_MACRO_3));
        }

        int iTotalDouble =
                DOUBLE_ANTI_MACRO_5 + (stRole.GetLevel()-stTargetRole.GetLevel()) * DOUBLE_ANTI_MACRO_4 + (int)dDoubleAnti;
        CT_BATTLE(("最终暴击率(%d) = %d + (A等级(%d)-B等级(%d)) * (%d) + 修正后暴击抗暴(%0.2lf)",
                    iTotalDouble,DOUBLE_ANTI_MACRO_5,stRole.GetLevel(),stTargetRole.GetLevel(),DOUBLE_ANTI_MACRO_4,dDoubleAnti));

        if (iTotalDouble < BATTLE_RATE_DOUBLE_AMEND_MIN)
        {
            iTotalDouble = BATTLE_RATE_DOUBLE_AMEND_MIN;
            CT_BATTLE(("最终暴击率强制修正为(%d)!",iTotalDouble));
        }

        bool bIsDouble = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION) < iTotalDouble; 
        if (bIsDouble)
        {
            if (!_bTriggerDeadKill)//斩杀效果 若斩杀不传暴击位
            {
                iSkillTargetStat |= BATTLE_VIDEO_SKILL_DOUBLE;
            }

            //必杀是一个千分比而不是等级
            int iCrit = stRole.GetTypeAttr(EXT_ATTR_CRIT, bIsFirst);
            if (iCrit < 0){iCrit = 0;}
            _i64AtkValue *= (INT64_1 * (BATTLE_RATE_DOUBLE_ADD + iCrit));
            _i64AtkValue /= BATTLE_RATE_SKILL_PERCENT;

            CT_BATTLE(("出现暴击且暴击后伤害为(%lld)",_i64AtkValue));
        }

        //格档
        if (stSkillCastEffect._astTargets[i].IsBlock())
        {
            iSkillTargetStat |= BATTLE_VIDEO_SKILL_BLOCK;

            _i64AtkValue /= 2;
            CT_BATTLE(("目标格档且格档后伤害为(%lld)",_i64AtkValue));
        }

        //目标免伤修正 免伤是一个千分比而不是等级
        int iImInjury = stTargetRole.GetTypeAttr(EXT_ATTR_IMMUNE_INJURY, bIsFirst);
        if (iImInjury < 0)
        {
            iImInjury = 0;
        }
        else if (iImInjury >= BATTLE_RATE_SKILL_PERCENT)
        {
            iImInjury = BATTLE_RATE_IMMUNE_INJURY_MAX;
        }

        _i64AtkValue *= (INT64_1 * (BATTLE_RATE_SKILL_PERCENT - iImInjury));
        _i64AtkValue /= BATTLE_RATE_SKILL_PERCENT;
        CT_BATTLE(("免伤计算后伤害为(%lld):目标免伤值(%d)",_i64AtkValue,iImInjury));

        //状态处理 STATUS_TRIGGER_CALC_SKILL_EFF
        //计算伤害时触发 这里调用仅为修正_i64AtkValue
        CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
             CStatusMgr::STATUS_TRIGGER_CALC_SKILL_EFF, 0);

        //状态处理 STATUS_TRIGGER_CALC_ATK_OBJ_LIMIT 
        //计算伤害时触发 要求检查目标临界值 为修正_i64AtkValue 
        CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
             CStatusMgr::STATUS_TRIGGER_CALC_ATK_OBJ_LIMIT, 0);

        //修正战斗伤害
        ReviseAttackValue(stRole, stTargetRole);

        //减血
        if (_i64AtkValue < 0)
        {
            CT_WARNING(("attack value(%lld) invalid, change 0",_i64AtkValue));
            _i64AtkValue = 0;
        }
        else if (_i64AtkValue > (int64)0x7FFFFFFF)
        {
            CT_WARNING(("attack value(%lld) too large",_i64AtkValue));
        }

        int iLostBlood = (int)(_i64AtkValue & 0x7FFFFFFF);
        //iBloodChg来自技能直接修改血量 正为加血 负为扣血 这里转换
        iLostBlood = iBloodChg - iLostBlood;

        //有些技能不计算伤害掉血比如预处理技能 但是必须走完所有可能的状态触发流程
        if (!stSkill.GetNoAttack())
        {
            if (BATTLE_RULE_STAT_PRE_SKILL != GetRuleStat())
            {
                stTargetRole.ChgBlood(iLostBlood);
                
                int iHitBackGird = -1;
                int iPullGird = -1;
                
                if (stSkillCastEffect._astTargets[i].GetHitBackDistance() > 0)
                {
                    iHitBackGird = iTargetGridPos;
                }
                else if (stSkillCastEffect._astTargets[i].GetPullDistance() > 0)
                {
                    iPullGird = iTargetGridPos;
                }
            
                BATTLE_INF->_pstVideo->LostBloodBySkill(stTargetRole.GetRoleID(), iSkillTargetStat, iLostBlood,
                    iHitBackGird, iPullGird);
            
                stTargetRole.RoleAttrChg(iTargetHPBefore);
            }
            else
            {
                stTargetRole.ModRoleHP(iLostBlood, stRole.GetRoleID());
            }
        }

        if (bIsToEnemy)
        {
            //状态处理 STATUS_TRIGGER_HIT_ENEMY //命中敌人时触发 攻击者触发+
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                 CStatusMgr::STATUS_TRIGGER_HIT_ENEMY, 0);

            //状态处理 STATUS_TRIGGER_ENEMY_HIT //命中敌人时触发 被攻击者触发+
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                 CStatusMgr::STATUS_TRIGGER_ENEMY_HIT, 0);
        }

        //状态处理 STATUS_TRIGGER_NORMAL_SKILL_HIT //普通攻击命中敌人时触发 +
        if (bIsToEnemy)
        {
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                 CStatusMgr::STATUS_TRIGGER_NORMAL_SKILL_HIT, 0);
        }

        if (bIsDouble)
        {
            //状态处理 STATUS_TRIGGER_ATK_DOUBLE //攻击暴击时触发
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                CStatusMgr::STATUS_TRIGGER_ATK_DOUBLE, 0);

            //状态处理 STATUS_TRIGGER_NORMAL_SKILL_DOUBLE //普通攻击暴击敌人时触发 +
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                CStatusMgr::STATUS_TRIGGER_NORMAL_SKILL_DOUBLE, 0);

            //状态处理 STATUS_TRIGGER_BY_DOUBLE //受击被暴击时触发
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                CStatusMgr::STATUS_TRIGGER_BY_DOUBLE, 0);
        }

        if (stSkillCastEffect._astTargets[i].IsBlock())
        {
            //状态处理 STATUS_TRIGGER_ATK_BLOCK //攻击被格挡时触发
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
                CStatusMgr::STATUS_TRIGGER_ATK_BLOCK, 0);

            //状态处理 STATUS_TRIGGER_BLOCK_ATK //格挡攻击时触发
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTargetRole,
                CStatusMgr::STATUS_TRIGGER_BLOCK_ATK, 0);
        }
    }

    int iTargetDeadNum = 0;
    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        if (stSkillCastEffect._astTargets[i].IsHitted() && bIsToEnemy)
        {
            if (!BATTLE_INF->_pstRoles->IsValidRoleID(
                    stSkillCastEffect._astTargets[i].GetID()))
            {
                continue;
            }
            CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(
                    stSkillCastEffect._astTargets[i].GetID());
            if (stTargetRole.HasDead())//统一输出死亡
            {
                BATTLE_INF->_pstRules->SetNowKiller(stRole.GetRoleID());

                //状态处理 STATUS_TRIGGER_SELF_DIE //自己死亡时触发
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                    stTargetRole, CStatusMgr::STATUS_TRIGGER_SELF_DIE, 0);

                //状态处理 STATUS_TRIGGER_SELF_DIE_ALL_DIE
                //自己死亡时触发 且是本方最后一个死亡 +
                CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                    stTargetRole, CStatusMgr::STATUS_TRIGGER_SELF_DIE_ALL_DIE,
                    0);

                if (GetNowDeader() != stTargetRole.GetRoleID())
                {
                    //BATTLE_INF->_pstVideo->RoleDead(stTargetRole.GetRoleID());
                    AddSkillDead(stTargetRole.GetRoleID());
                }

                ++iTargetDeadNum;
            }
        }
    }

    if (iTargetDeadNum > 0)
    {
        //状态处理 STATUS_TRIGGER_ATK_OBJ_DIE //攻击目标死亡时触发
        CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stRole,
            CStatusMgr::STATUS_TRIGGER_ATK_OBJ_DIE, iTargetDeadNum - 1);
    
        CMapSide& stMapSideTemp = BATTLE_INF->_pstMap->GetMapSide(!stRole.IsLeft());
        MAP_GRID_MULTI stMapGridMulti;
        stMapSideTemp.GetDistanceRoles(0, stMapSideTemp.GetLeftFrontTo(), stMapGridMulti);
        for (int i = 0; i < stMapGridMulti.Size(); ++i)
        {
            if (!BATTLE_INF->_pstRoles->IsValidRoleID(
                    stMapGridMulti[i].GetRoleID()))
            {
                continue;
            }
            CBattleRole& stTeamRole =
                BATTLE_INF->_pstRoles->GetRole(stMapGridMulti[i].GetRoleID());
        
            //状态处理 STATUS_TRIGGER_TEAMMATE_DIE //队友死亡时触发
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(stTeamRole,
                CStatusMgr::STATUS_TRIGGER_TEAMMATE_DIE, iTargetDeadNum - 1);
        }
    }

    return 0;
}

int CBattleRules::SkillEffect3(CBattleRole& stRole, CSkill& stSkill,
        CBattleSkillCastEffect& stSkillCastEffect)
{
    int iRet = 0;
    if (stRole.HasDead())
    {
        return 0;
    }

    if (!stSkillCastEffect.IsToEnemy() ||
        !stSkill.MainSkillHasMainTargetStru() ||
        stSkillCastEffect._astTargets.Size() <= 0 )
    {
        return 0;
    }

    int iRoleID = stSkillCastEffect._astTargets[0].GetID();
    CT_BATTLE(("受击者(%d)对施法者(%d)反击计算开始",iRoleID,stRole.GetRoleID()));
    if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
    {
        return 0;
    }

    CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
    if (stTargetRole.HasDead() || stTargetRole.IsSwim())
    {
        CT_BATTLE(("受击者(%d)已死亡(%d)或者眩晕(%d)",
                    stTargetRole.GetRoleID(),stTargetRole.HasDead(),stTargetRole.IsSwim()));
        return 0;
    }

    if (stSkillCastEffect._astTargets[0].GetHitBackDistance() > 0
        || stSkillCastEffect._astTargets[0].GetPullDistance() > 0
        || !stSkillCastEffect._astTargets[0].IsBlock())
    {
        CT_BATTLE(("受击者(%d)被击飞(%d)被拖拽(%d)没有格挡(%d)",
                    stTargetRole.GetRoleID(),
                    stSkillCastEffect._astTargets[0].GetHitBackDistance(),
                    stSkillCastEffect._astTargets[0].GetPullDistance(),
                    !stSkillCastEffect._astTargets[0].IsBlock()));
        return 0;
    }

    if (!stTargetRole.CanCastNormalSkill())
    {
        CT_BATTLE(("受击者(%d)没有配置普通技能(%d)",
                    stTargetRole.GetRoleID(),stTargetRole._stRoleBase._stNormalSkill.GetID()));
        return 0;
    }

    CSkill stNormalSkill;
    stTargetRole.GetNormalSkill(stNormalSkill);
    
    SetSkillType(stNormalSkill.GetType());

    CBattleSkillCastEffect stHitBackCastEffect;
    CBattleSkillCastEffect stHitBackCastEffectTmp;

    iRet = stNormalSkill.GetMainSkillAffect(stHitBackCastEffect._stSkillAffect);
    CT_RETURN(iRet);

    SetNowAttack(stTargetRole.GetRoleID()); //设置当前攻击者ID
    SetNowTarget(stRole.GetRoleID()); //设置当前受击者ID

    stHitBackCastEffect._chTargetType = VIDEO_EXE_SKILL_SCOPE_MAIN;
    stHitBackCastEffect._chTargetFromPos = stRole.GetGridIndex();
    stHitBackCastEffect._chTargetEndPos = stRole.GetGridIndex();

    bool bLeftSide = stTargetRole.IsLeft();
    int iDistance = stRole.GetRelatGridIndex(bLeftSide) - stTargetRole.GetRelatGridIndex(bLeftSide);

#define BATTLE_FIGHT_BACK_LIMIT 2   //大于此距离不执行反击
    if (iDistance <= 0 || iDistance > BATTLE_FIGHT_BACK_LIMIT)
    {
        return 0;
    }

    CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(bLeftSide);

    int iAtkDist = stHitBackCastEffect._stSkillAffect.GetMaxAtkDistance();
    iAtkDist = iAtkDist < 0 ? 0 : iAtkDist;

    int iAddDist = stTargetRole.IsStick() ? 0 : stMapSide.GetRightFrontTo() - stTargetRole.GetRelatGridIndex(bLeftSide);
    if (iDistance > iAddDist + iAtkDist)
    {
        CT_BATTLE(("受击者(%d 被定身(%d))与施法者(%d)的距离(%d)大于可移动距离(%d)+攻击距离(%d)",
                    stTargetRole.GetRoleID(),stTargetRole.IsStick(),stRole.GetRoleID(),iDistance,iAddDist,iAtkDist));
        return 0;
    }

    int iRandom = CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION);

    CT_BATTLE(("受击者(%d)反击率(%d)反击随机概率(%d)",
                stTargetRole.GetRoleID(),stTargetRole.GetTypeAttr(EXT_ATTR_FIGHT_BACK, true),iRandom));

    if (iRandom < stTargetRole.GetTypeAttr(EXT_ATTR_FIGHT_BACK, true))
    {
        stTargetRole._iUseAnger = 0;//用于记录本次高阶技能消耗的怒气 因为只用普通技能反击 不消耗怒气
        _stBattleReviseAtk.Clear();
        BattleReviseInit(stTargetRole);//确定反击才会加入伤害修正状态

        //反击
        CBattleSkillTarget stHitBackSkillTarget(stRole.GetRoleID());
        stHitBackCastEffect._astTargets.AddOneItem(stHitBackSkillTarget);

        iRet = CastSkill(stTargetRole, stNormalSkill, stRole.GetRoleID());
        CT_RETURN(iRet);

        iRet = stTargetRole.CastSkill(stNormalSkill);
        CT_RETURN(iRet);
        
        //记录技能释放
        BATTLE_INF->_pstVideo->CastSkill(stTargetRole.GetRoleID(),
            stNormalSkill.GetID(), stNormalSkill.GetTargetType(),
            stHitBackCastEffect, stHitBackCastEffectTmp);
        
        //检查命中
        iRet = CastSkillEffectHitRateCheck(stTargetRole, stHitBackCastEffect, true);
        CT_RETURN(iRet);
        
        //格档
        iRet = CastSkillEffectBlockCheck(stTargetRole, stHitBackCastEffect, true);
        CT_RETURN(iRet);
        
        //击飞
        iRet = CastSkillEffectHitBackCheck(stTargetRole, stHitBackCastEffect);
        CT_RETURN(iRet);
        
        //拖拽
        iRet = CastSkillEffectPullCheck(stTargetRole, stHitBackCastEffect);
        CT_RETURN(iRet);

        ClearSkillDead();
        ClearSkillRandom();

        //伤害计算
        iRet = SkillEffect2(stTargetRole, stNormalSkill, stHitBackCastEffect, true);
        CT_RETURN(iRet);

        VideoAllSkillRoleDead();//同一技能统一输出死亡

        //撤退
        iRet = SkillEffect4(stTargetRole, stNormalSkill, stHitBackCastEffect);
        CT_RETURN(iRet);
    }

    CT_BATTLE(("受击者(%d)对施法者(%d)反击计算结束",
        stSkillCastEffect._astTargets[0].GetID(),stRole.GetRoleID()));

    //恢复设置
    SetNowAttack(stRole.GetRoleID()); //设置当前攻击者ID
    SetNowTarget(-1); //设置当前受击者ID

    return 0;
}

int CBattleRules::SkillEffect4(CBattleRole& stRole, CSkill& stSkill,
        CBattleSkillCastEffect& stSkillCastEffect)
{
    int iRet = 0;
    for (int i = 0; i < stSkillCastEffect._astTargets.Size(); ++i)
    {
        CBattleSkillTarget& stSkillTarget = stSkillCastEffect._astTargets[i];
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(stSkillTarget.GetID()))
        {
            continue;
        }
        CBattleRole& stTargetRole =
            BATTLE_INF->_pstRoles->GetRole(stSkillTarget.GetID());
        if (stTargetRole.HasDead())
        {
            continue;
        }
        
        if (!stTargetRole.IsFallBackRightNow())
        {
            continue;
        }

        if (stSkillTarget.GetPullDistance() <= 0 &&
            stSkillTarget.GetHitBackDistance() <= 0 &&
            !stTargetRole.IsSwim() && !stTargetRole.IsStick())
        {
            BATTLE_INF->_pstVideo->RoleFallBack(stTargetRole.GetRoleID());

            bool bLeftSide = stTargetRole.IsLeft();
            int iDstGrid = CT_MAX(0, stTargetRole.GetRelatGridIndex(bLeftSide) - BATTLE_FALLBACK_DISTANCE);
            if (iDstGrid != stTargetRole.GetRelatGridIndex(bLeftSide))
            {
                iRet = RoleMoveTo(stTargetRole, iDstGrid, true);
                CT_RETURN(iRet);
                CT_BATTLE(("角色(%d)撤退到格子(%d)",stTargetRole.GetRoleID(),stTargetRole.GetGridIndex()));
            }

            stTargetRole.SetRoleTurnWait();
        }
    }

    return 0;
}

void CBattleRules::DumpRoleAndTargetInfo(CBattleRole& stRole)
{
    //注意：施法者及受击者需且仅需输出一次
    bool abHasInit[MAX_BATTLE_ROLES];
    for (int i = 0; i < MAX_BATTLE_ROLES; ++i)
    {
        abHasInit[i] = false;
    }

    //施法者
    CT_BATTLE(("施法者:"));
    stRole.DumpRoleInfo(true);
    abHasInit[stRole.GetRoleID()] = true;//战场ID即下标

    //受击者
    CT_BATTLE(("受击者:"));
    int iRoleID = 0;
    for (int i = 0; i < _stSkillCastFirstEffect._astTargets.Size(); ++i)
    {
        iRoleID = _stSkillCastFirstEffect._astTargets[i].GetID();
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
        if (!abHasInit[stTargetRole.GetRoleID()])
        {
            stTargetRole.DumpRoleInfo(true);
            abHasInit[stTargetRole.GetRoleID()] = true;//战场ID即下标
        }
    }

    for (int i = 0; i < _stSkillCastSecondEffect._astTargets.Size(); ++i)
    {
        iRoleID = _stSkillCastSecondEffect._astTargets[i].GetID();
        if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
        {
            continue;
        }
        CBattleRole& stTargetRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
        if (!abHasInit[stTargetRole.GetRoleID()])
        {
            stTargetRole.DumpRoleInfo(true);
            abHasInit[stTargetRole.GetRoleID()] = true;//战场ID即下标
        }
    }
}

void CBattleRules::DumpRulesInfo()
{
    CT_BATTLE(("%s", "---- BeginRulesInfo ----"));
    CT_BATTLE(("%-18s = %d", "TurnOver", _bTurnOver));
    CT_BATTLE(("%s", "-- CastSkillInfo --"));
    CT_BATTLE(("%s", "-- SkillCastFirstEffect --"));
    _stSkillCastFirstEffect.DumpSkillCastEffectInfo();
    CT_BATTLE(("%s", "-- SkillCastSecondEffect --"));
    _stSkillCastSecondEffect.DumpSkillCastEffectInfo();
    CT_BATTLE(("%s", "---- EndRulesInfo ----"));
}

void CBattleSkillCastEffect::DumpSkillCastEffectInfo()
{
    CT_BATTLE(("%s", "-- SkillAffect --"));
    //_stSkillAffect.DumpSkillAffectInfo();
    CT_BATTLE(("Skill Target Size (%d)", _astTargets.Size()));
    for (int i = 0; i < _astTargets.Size(); ++i)
    {
        CT_BATTLE(("Skill Target Index (%d)", i));
        _astTargets[i].DumpSkillTargetInfo();
    }
}

void CBattleSkillTarget::DumpSkillTargetInfo()
{
    CT_BATTLE(("%-18s = %d", "ID", _iID));
    CT_BATTLE(("%-18s = %d", "Hitted", _bHitted));
    CT_BATTLE(("%-18s = %d", "IsBlock", _bIsBlock));
    CT_BATTLE(("%-18s = %d", "HitBackDistance", _iHitBackDistance));
    CT_BATTLE(("%-18s = %d", "PullDistance", _iPullDistance));
}

